![]() |
program is not crashing, after 10 iteration
Hi All ,
the program is not crashing, after 10 iteration of the loop; int main( ) { int * ptr = (int *)malloc( 10) ; while( 1 ) { printf(" %d \n",*ptr); ptr++ ; } } Thanks Pallav Singh |
Re: program is not crashing, after 10 iteration
"Pallav singh" <singh.pallav@gmail.com> wrote in message
news:bdf2cdf2-4a67-4696-9111-8002d8c8425a@l35g2000pra.googlegroups.com > Hi All , > > the program is not crashing, after 10 iteration of the > loop; > > int main( ) > { > int * ptr = (int *)malloc( 10) ; > while( 1 ) > { > printf(" %d \n",*ptr); > ptr++ ; > } > } > > Thanks > Pallav Singh Why do you think it should crash after 10 iterations? You allocate 10 bytes, which may take only 2 ints on a 32-bit machine, so if it crashes, it might do it after 2 iterations. But indefinded behaviour is undefined behavior. It may do whatever it pleases. As it does not write to the unallocated memory, it propably just prints whatever happens to be there. As you do not initilise the allocated memory anyhow, the result is undefined from the first iteration already. |
Re: program is not crashing, after 10 iteration
On Jul 18, 1:25*pm, Pallav singh <singh.pal...@gmail.com> wrote:
> the program is not crashing, after 10 iteration of the loop; There's really no reason why it should. Operations like malloc() and new[] don't allocate the exact amount of memory you ask for, and then return a pointer to it. Instead they find _at least_ that much memory free and give you a pointer to that, expecting that you'll obey the bounds. This is to make memory management faster and easier. BTW, this behaviour is usually called buffer overrun/overflow. Check out the wikipedia article. Note also that this is one of the areas where C/C++ lets you hang yourself. Java (AFAIK), checks bounds on every array access and will raise an exception if you go out of bounds. --Jonathan |
Re: program is not crashing, after 10 iteration
Andy Champ wrote:
> I'd say to anyone stay away from malloc. It's dangerous. Use the STL > stuff to manage memory, it's much safer. > > And if you can come up with a good reason why to use malloc you probably > know enough to know when to break the rule. It occurs to me that _I_ > haven't use malloc all year. A related question: If you really need to allocate uninitialized memory for whatever reason (eg. you are writing your own memory allocator, some kind of memory pool, or other such low-level thing), is there any practical difference between using std::malloc() and ::new? Should one be preferred over the other? |
Re: program is not crashing, after 10 iteration
* Juha Nieminen:
> Andy Champ wrote: >> I'd say to anyone stay away from malloc. It's dangerous. Use the STL >> stuff to manage memory, it's much safer. >> >> And if you can come up with a good reason why to use malloc you probably >> know enough to know when to break the rule. It occurs to me that _I_ >> haven't use malloc all year. > > A related question: If you really need to allocate uninitialized > memory for whatever reason (eg. you are writing your own memory > allocator, some kind of memory pool, or other such low-level thing), is > there any practical difference between using std::malloc() and ::new? The latter is compatible with your app's overall other error handling. How to deal with memory exhaustion is a difficult topic, though. For small allocations you want to rely on a terminating new-handler or other scheme that terminates, instead of the default std::bad_alloc exception. But say you're loading a large picture and that allocation might fail. In that case your app is usually /not/ hopelessly screwed if the allocation fails, so in that case you may want the exception, and just report load failure to the user. What's difficult is what to do for the terminating case. Do you just log (if you have logging) and terminate, or do you let your app have a go at cleaning up, via some "hard exception" scheme with stack unwinding up to the top? The problem with the unwinding is that if the failure is caused by a small allocation, or e.g. if there's a memory-gobbling thread or process around, then even just making an attempt at cleanup might make matters worse, e.g. one might end up with hanging program and no log entry. Debates about this have been endless with no firm conclusion, only that some people find one or the other idea horrible and signifying the utter incompetence and perhaps even lack of basic intellect of those arguing the other view. :-) > Should one be preferred over the other? Yes. ;-) Cheers & hth., - Alf |
Re: program is not crashing, after 10 iteration
On Jul 18, 10:10 pm, "Alf P. Steinbach" <al...@start.no> wrote:
> * Juha Nieminen: > > Andy Champ wrote: > >> I'd say to anyone stay away from malloc. It's dangerous. > >> Use the STL stuff to manage memory, it's much safer. > >> And if you can come up with a good reason why to use malloc > >> you probably know enough to know when to break the rule. > >> It occurs to me that _I_ haven't use malloc all year. > > A related question: If you really need to allocate > > uninitialized memory for whatever reason (eg. you are > > writing your own memory allocator, some kind of memory pool, > > or other such low-level thing), is there any practical > > difference between using std::malloc() and ::new? > The latter is compatible with your app's overall other error > handling. Note that when dealing with raw memory, I prefer ::operator new(n) to ::new char[n]. IMHO, it expresses the intent better. > How to deal with memory exhaustion is a difficult topic, > though. Except when it's easy:-). > For small allocations you want to rely on a terminating > new-handler or other scheme that terminates, instead of the > default std::bad_alloc exception. Which makes it easy:-). (And a lot of applications can use this strategy.) > But say you're loading a large picture and that allocation > might fail. In that case your app is usually /not/ hopelessly > screwed if the allocation fails, so in that case you may want > the exception, and just report load failure to the user. Or you might want to change strategies, spilling part of the data to disk, in which case, you'd use new(nothrow). The problem here is that when it "just fits", you might still end up using so much memory that the machine starts thrashing. This is one of the cases where memory exhaustion is a difficult topic. > What's difficult is what to do for the terminating case. > Do you just log (if you have logging) and terminate, or do you > let your app have a go at cleaning up, via some "hard > exception" scheme with stack unwinding up to the top? The > problem with the unwinding is that if the failure is caused by > a small allocation, or e.g. if there's a memory-gobbling > thread or process around, then even just making an attempt at > cleanup might make matters worse, e.g. one might end up with > hanging program and no log entry. Debates about this have been > endless with no firm conclusion, only that some people find > one or the other idea horrible and signifying the utter > incompetence and perhaps even lack of basic intellect of those > arguing the other view. :-) There's also the problem that the logging mechanism might try to allocate (which will fail). One strategy that I've seen used with success (although I don't think there's any hard guarantee) is to "pre-allocate" a couple of KB (or maybe an MB today) up front---the new handler then frees this before starting the log and abort procedure. > > Should one be preferred over the other? > Yes. ;-) -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
Re: program is not crashing, after 10 iteration
Pallav singh <singh.pallav@gmail.com> writes:
> Hi All , > > the program is not crashing, after 10 iteration of the loop; > > int main( ) > { > int * ptr = (int *)malloc( 10) ; > while( 1 ) > { > printf(" %d \n",*ptr); > ptr++ ; > } > } Check the other discussion "Books for advanced C++ debugging". This is formally an "undefined behavior" situation. We plain programmers would like the implementation to throw an exception when such a situation occurs. But it would be more work for compiler writters, so they don't want to provide such a feature (much less optionnaly, since that would be even more work). And therefore the industry must bear the cost of uncaught bugs, of which viruses and worms take benefit. Personnaly, the only solution I see is to forget C and C++ and instead use implementations of different programming languages that provide such run-time checks and error detection, be it because the implementers of these other programming languages are not as stubborn as C or C++ implementers, or because those other programming languages define such an error checking behavior. Just for an example of such another culture, here is what you'd get with Common Lisp (but most other programming languages detect these errors): C/USER[29]> (declaim (optimize (safety 0) (debug 0) (speed 3) (space 2))) NIL C/USER[30]> (defun main () (let ((ptr (make-array 10 :element-type 'integer :initial-element 0))) (loop for i from 0 do (format t " ~D ~^" (aref ptr i))))) MAIN C/USER[31]> (main) 0 0 0 0 0 0 0 0 0 0 *** - AREF: index 10 for #(0 0 0 0 0 0 0 0 0 0) is out of range The following restarts are available: ABORT :R1 Abort main loop C/Break 1 USER[32]> -- __Pascal Bourguignon__ |
Re: program is not crashing, after 10 iteration
Pascal J. Bourguignon wrote:
> Pallav singh <singh.pallav@gmail.com> writes: > >> Hi All , >> >> the program is not crashing, after 10 iteration of the loop; >> >> int main( ) >> { >> int * ptr = (int *)malloc( 10) ; >> while( 1 ) >> { >> printf(" %d \n",*ptr); >> ptr++ ; >> } >> } > > Check the other discussion "Books for advanced C++ debugging". > > This is formally an "undefined behavior" situation. > > We plain programmers would like the implementation to throw an > exception when such a situation occurs. > > But it would be more work for compiler writters, so they don't want > to > provide such a feature (much less optionnaly, since that would be > even > more work). And therefore the industry must bear the cost of > uncaught > bugs, of which viruses and worms take benefit. > > > Personnaly, the only solution I see is to forget C and C++ and > instead > use implementations of different programming languages that provide > such run-time checks and error detection, be it because the > implementers of these other programming languages are not as > stubborn > as C or C++ implementers, or because those other programming > languages > define such an error checking behavior. > Not the only solution. :-) The other solution is of course to use those parts of C++ that gives you the security you want (and leave the unchecked code for the places where it is really needed). int main() { std::vector<int> p(10); int i = 0; while(1) { std::cout << p.at(i) << std::endl; ++i; } } Bug caught at runtime! Of course, if you chose to iterate from p.begin() to p.end() you have no chance of stepping outside the vector. Safety! Bo Persson |
Re: program is not crashing, after 10 iteration
In article <7ck523lnes.fsf@pbourguignon.anevia.com>,
pjb@informatimago.com says... [ ... ] > Personnaly, the only solution I see is to forget C and C++ and > instead use implementations of different programming languages that > provide such run-time checks and error detection, be it because the > implementers of these other programming languages are not as > stubborn as C or C++ implementers, or because those other > programming languages define such an error checking behavior. Actually, there's a much better solution than changing languages. Though it's virtually never put to use, x86 CPUs (for one example) could implement such checks in hardware if we just put to use what's been there for years. Specifically, an x86 running protected mode uses segments, and each segment has a base and a limit. The problem is that right now, every major OS basically ignores the segments -- they're all set up with a base of 0 and a limit of 4 GiB (technically there _are_ segments for which this isn't true, but the stack, data and code segments are set up this way, so most normal uses have access to all memory). Now, it is true that as currently implemented, segments have some shortcomings -- in particular, there are only 6 available segment registers, and loading a segment register is a comparatively expensive operation, so when you use segments code will usually run a bit slower. The slowdown from doing the job in hardware is a lot smaller than the slowdown from doing it in software though. The other problem is that Intel's current implementation uses only 16 bit segment registers, so you can only define 65,536 segments at a time. This is mostly an accident of history though -- the segmentation scheme originated with the 286, when none of the registers was larger than that. The OS that ever put it to use was OS/2 1.x, so it's received only the most minimal updates necessary to allow access to more memory. OTOH, keep in mind that the 286 had four segment registers and all the associated hardware for checking segment access. Expanding the hardware to include (for example) 32 segments of 32 bits apiece wouldn't be a huge addition to the size of today's chips. Absent that, C++ provides (but doesn't force you to use) about as good of checking as most other languages. In particular, things like std::vector include both operator[] and the at() member function. The former doesn't require bounds checking, but the latter does. IMO, the biggest problem is that they should have reversed the two: the easy, more or less default choice, should also be the safe one. Bypassing the safety of a bounds check should be what requires longer code with rather oddball syntax that's easy to spot. In that case, seeing 'at(x)' during a code inspection would be almost the same level of red flag as, say, a reinterpret_cast is. -- Later, Jerry. |
Re: program is not crashing, after 10 iteration
"Jerry Coffin" <jerryvcoffin@yahoo.com> > Specifically, an x86 running protected mode uses segments, and each > segment has a base and a limit. The problem is that right now, every > major OS basically ignores the segments -- they're all set up with a > base of 0 and a limit of 4 GiB (technically there _are_ segments for > which this isn't true, but the stack, data and code segments are set > up this way, so most normal uses have access to all memory). > > Now, it is true that as currently implemented, segments have some > shortcomings -- in particular, there are only 6 available segment > registers, and loading a segment register is a comparatively > expensive operation, so when you use segments code will usually run a > bit slower. The slowdown from doing the job in hardware is a lot > smaller than the slowdown from doing it in software though. > > The other problem is that Intel's current implementation uses only 16 > bit segment registers, so you can only define 65,536 segments at a > time. The selector's last bits are reserved, so IIRC in a descriptor table you only have 2x8k segments. Though there are ways to manipulate the descriptor table. OTOH In practice having 8k segments for a process looks quite enough. > This is mostly an accident of history though -- the > segmentation scheme originated with the 286, when none of the > registers was larger than that. 386 introduced 32 bit extended regs for all the regular regs, it could have done the same for selectors... but it would not resolve a real life problem. > The OS that ever put it to use was OS/2 1.x, IIRC Xenix used the segmented model too both on 286 and 386 versions. NT uses segments deep in the kernel. |
| All times are GMT. The time now is 08:40 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.