Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Realloc destroys?

Reply
Thread Tools

Realloc destroys?

 
 
Marc Thrun
Guest
Posts: n/a
 
      10-11-2005
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> Here is something new,
> if the first time i malloc(15*sizeof(*Reqs)) it works fine. So i
> commented the Realloc part in the function i tried it. But Something i
> did not expect ,happened, it didn't just stored 15 items but it seemed
> to be "endless", i stored tons of items as if there was no need for a
> Realloc. WHY?!.
>
> (E-Mail Removed) ha escrito:
>
>

If you write more items than you have allocated space for, you invoke
undefined behaviour which allows anything to happen. It might even seem
to work though you might corrupt some other memory.
 
Reply With Quote
 
 
 
 
ifmusic@gmail.com
Guest
Posts: n/a
 
      10-12-2005
but why? all i did is :
in the Main i declared te pointers and i malloc'd these "endless"
pointer to
15, so i thought, ok i should have space to store 15 entries. Found
out, i can store way more than that.
"undefined behaviour", i think i was trying to do Something Well
defined But when i tried to store a couple of entries i got my
beautiful segmentation code, that's why i malloc'd 15, though i never
expected this to happen.

I'll try to post an extract of my program with everything that could be
related to the List of pointers to pointers.

Thank you all for answering so fast!

> >

> If you write more items than you have allocated space for, you invoke
> undefined behaviour which allows anything to happen. It might even seem
> to work though you might corrupt some other memory.


 
Reply With Quote
 
 
 
 
ifmusic@gmail.com
Guest
Posts: n/a
 
      10-12-2005
that's a good question.
-after checking it out, it does not Seg Fault when i'm storing but
actually
when i'm printing the results. I mean, after adding the fifth item , i
call for a
printing function which is basically a For going through the structure,
but
it hangs (seg faults) inmediatelly, not in the second, fourth or
fifth....

i'll give you more info soon.
But tell me if you got any clues.

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      10-12-2005
(E-Mail Removed) writes:
> but why? all i did is :
> in the Main i declared te pointers and i malloc'd these "endless"
> pointer to
> 15, so i thought, ok i should have space to store 15 entries. Found
> out, i can store way more than that.
> "undefined behaviour", i think i was trying to do Something Well
> defined But when i tried to store a couple of entries i got my
> beautiful segmentation code, that's why i malloc'd 15, though i never
> expected this to happen.
>
> I'll try to post an extract of my program with everything that could be
> related to the List of pointers to pointers.
>
> Thank you all for answering so fast!
>
>> >

>> If you write more items than you have allocated space for, you invoke
>> undefined behaviour which allows anything to happen. It might even seem
>> to work though you might corrupt some other memory.


Please post properly. Google makes this unnecesarily difficult, but
the instructions have been posted here over 1000 times (that's not an
exaggeration). Here they are again:

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

Please complain to Google about their broken interface.

Based on your description, and without looking at whatever code
you posted earlier, you might find this instructive:

#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int *ptr;

ptr = malloc(5 * sizeof *ptr);
if (ptr == NULL) {
fprintf(stderr, "malloc() failed\n");
exit(EXIT_FAILURE);
}

/*
* ptr now points to an allocated array of 5 integers.
* ptr[0] refers to element 0 of the array.
* ptr[4] refers to the last element of the array.
*/

ptr[0] = 37;
printf("ptr[0] = %d\n", ptr[0]);
/*
* Ok so far.
*/

ptr[4] = 42;
printf("ptr[4] = %d\n", ptr[4]);
/*
* Still ok; we've just stored a value in the last
* allocated element of the array.
*/

ptr[5] = 77;
printf("ptr[5] = %d\n", ptr[5]);
/*
* This invokes undefined behavior by writing past the end
* of the allocated memory.
*/

return 0;
}

When I compiled and ran this program, I got the following output:

ptr[0] = 37
ptr[4] = 42
ptr[5] = 77

As soon as I assigned a value to ptr[5], I invoked undefined behavior,
because I wrote to memory that I didn't necessarily own. "Undefined
behavior" does *not* mean that the program is going to fail; it means
that, as far as the standard is concerned, the program can do
literally anything -- including behaving exactly as you might think it
should.

You said you thought you had space for 15 entries, but you found you
could store more than that. Storing more than 15 entries is
(presumably) an error, but the implementation isn't obligated to
detect the error. It can just go ahead and store the additional data
wherever you tell it to, even if it steps on other data (other
variables, system data, whatever) while it's doing so.

The responsibility for avoiding undefined behavior is entirely yours.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
ifmusic@gmail.com
Guest
Posts: n/a
 
      10-12-2005
Wow, that's crazy, never thought C provided such little protection.
Ok, now i get that even though i could store all this items i should
try to find out how to allocate and make it work properly too.
now, this, is where i need some help with...
Keith Thompson ha escrito:

> (E-Mail Removed) writes:
> > but why? all i did is :
> > in the Main i declared te pointers and i malloc'd these "endless"
> > pointer to
> > 15, so i thought, ok i should have space to store 15 entries. Found
> > out, i can store way more than that.
> > "undefined behaviour", i think i was trying to do Something Well
> > defined But when i tried to store a couple of entries i got my
> > beautiful segmentation code, that's why i malloc'd 15, though i never
> > expected this to happen.
> >
> > I'll try to post an extract of my program with everything that could be
> > related to the List of pointers to pointers.
> >
> > Thank you all for answering so fast!
> >
> >> >
> >> If you write more items than you have allocated space for, you invoke
> >> undefined behaviour which allows anything to happen. It might even seem
> >> to work though you might corrupt some other memory.

>
> Please post properly. Google makes this unnecesarily difficult, but
> the instructions have been posted here over 1000 times (that's not an
> exaggeration). Here they are again:
>
> If you want to post a followup via groups.google.com, don't use
> the broken "Reply" link at the bottom of the article. Click on
> "show options" at the top of the article, then click on the
> "Reply" at the bottom of the article headers.
>
> Please complain to Google about their broken interface.
>
> Based on your description, and without looking at whatever code
> you posted earlier, you might find this instructive:
>
> #include <stdlib.h>
> #include <stdio.h>
> int main(void)
> {
> int *ptr;
>
> ptr = malloc(5 * sizeof *ptr);
> if (ptr == NULL) {
> fprintf(stderr, "malloc() failed\n");
> exit(EXIT_FAILURE);
> }
>
> /*
> * ptr now points to an allocated array of 5 integers.
> * ptr[0] refers to element 0 of the array.
> * ptr[4] refers to the last element of the array.
> */
>
> ptr[0] = 37;
> printf("ptr[0] = %d\n", ptr[0]);
> /*
> * Ok so far.
> */
>
> ptr[4] = 42;
> printf("ptr[4] = %d\n", ptr[4]);
> /*
> * Still ok; we've just stored a value in the last
> * allocated element of the array.
> */
>
> ptr[5] = 77;
> printf("ptr[5] = %d\n", ptr[5]);
> /*
> * This invokes undefined behavior by writing past the end
> * of the allocated memory.
> */
>
> return 0;
> }
>
> When I compiled and ran this program, I got the following output:
>
> ptr[0] = 37
> ptr[4] = 42
> ptr[5] = 77
>
> As soon as I assigned a value to ptr[5], I invoked undefined behavior,
> because I wrote to memory that I didn't necessarily own. "Undefined
> behavior" does *not* mean that the program is going to fail; it means
> that, as far as the standard is concerned, the program can do
> literally anything -- including behaving exactly as you might think it
> should.
>
> You said you thought you had space for 15 entries, but you found you
> could store more than that. Storing more than 15 entries is
> (presumably) an error, but the implementation isn't obligated to
> detect the error. It can just go ahead and store the additional data
> wherever you tell it to, even if it steps on other data (other
> variables, system data, whatever) while it's doing so.
>
> The responsibility for avoiding undefined behavior is entirely yours.
>
> --
> Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
> San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
> We must do something. This is something. Therefore, we must do this.


 
Reply With Quote
 
ifmusic@gmail.com
Guest
Posts: n/a
 
      10-12-2005
sorry about the posting thing, i hadnt realized...
hope this is the correct way...

Now It's killing me! Why does it crash on the Fifth element!
why not first?! or after a lot?!

Keith Thompson ha escrito:

> (E-Mail Removed) writes:
> > but why? all i did is :
> > in the Main i declared te pointers and i malloc'd these "endless"
> > pointer to
> > 15, so i thought, ok i should have space to store 15 entries. Found
> > out, i can store way more than that.
> > "undefined behaviour", i think i was trying to do Something Well
> > defined But when i tried to store a couple of entries i got my
> > beautiful segmentation code, that's why i malloc'd 15, though i never
> > expected this to happen.
> >
> > I'll try to post an extract of my program with everything that could be
> > related to the List of pointers to pointers.
> >
> > Thank you all for answering so fast!
> >
> >> >
> >> If you write more items than you have allocated space for, you invoke
> >> undefined behaviour which allows anything to happen. It might even seem
> >> to work though you might corrupt some other memory.

>
> Please post properly. Google makes this unnecesarily difficult, but
> the instructions have been posted here over 1000 times (that's not an
> exaggeration). Here they are again:
>
> If you want to post a followup via groups.google.com, don't use
> the broken "Reply" link at the bottom of the article. Click on
> "show options" at the top of the article, then click on the
> "Reply" at the bottom of the article headers.
>
> Please complain to Google about their broken interface.
>
> Based on your description, and without looking at whatever code
> you posted earlier, you might find this instructive:
>
> #include <stdlib.h>
> #include <stdio.h>
> int main(void)
> {
> int *ptr;
>
> ptr = malloc(5 * sizeof *ptr);
> if (ptr == NULL) {
> fprintf(stderr, "malloc() failed\n");
> exit(EXIT_FAILURE);
> }
>
> /*
> * ptr now points to an allocated array of 5 integers.
> * ptr[0] refers to element 0 of the array.
> * ptr[4] refers to the last element of the array.
> */
>
> ptr[0] = 37;
> printf("ptr[0] = %d\n", ptr[0]);
> /*
> * Ok so far.
> */
>
> ptr[4] = 42;
> printf("ptr[4] = %d\n", ptr[4]);
> /*
> * Still ok; we've just stored a value in the last
> * allocated element of the array.
> */
>
> ptr[5] = 77;
> printf("ptr[5] = %d\n", ptr[5]);
> /*
> * This invokes undefined behavior by writing past the end
> * of the allocated memory.
> */
>
> return 0;
> }
>
> When I compiled and ran this program, I got the following output:
>
> ptr[0] = 37
> ptr[4] = 42
> ptr[5] = 77
>
> As soon as I assigned a value to ptr[5], I invoked undefined behavior,
> because I wrote to memory that I didn't necessarily own. "Undefined
> behavior" does *not* mean that the program is going to fail; it means
> that, as far as the standard is concerned, the program can do
> literally anything -- including behaving exactly as you might think it
> should.
>
> You said you thought you had space for 15 entries, but you found you
> could store more than that. Storing more than 15 entries is
> (presumably) an error, but the implementation isn't obligated to
> detect the error. It can just go ahead and store the additional data
> wherever you tell it to, even if it steps on other data (other
> variables, system data, whatever) while it's doing so.
>
> The responsibility for avoiding undefined behavior is entirely yours.
>
> --
> Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
> San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
> We must do something. This is something. Therefore, we must do this.


 
Reply With Quote
 
Default User
Guest
Posts: n/a
 
      10-12-2005
(E-Mail Removed) wrote:

> sorry about the posting thing, i hadnt realized...
> hope this is the correct way...



Not quite. Your replies belong following or inspersed with the quotes.
See almost every other post on the newsgroup for the correct way.




Brian
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      10-12-2005
(E-Mail Removed) writes:
> sorry about the posting thing, i hadnt realized...
> hope this is the correct way...


Please don't top-post. Your response belongs below any quoted text,
and you should trim anything that's not relevant to your response.
See most of the articles in this newsgroup for exmaples.

> Now It's killing me! Why does it crash on the Fifth element!
> why not first?! or after a lot?!


That's the nature of undefined behavior. As long as you stay within
the bounds of your array, you're fine. As soon as you start stepping
on memory outside your array, you invoke undefined behavior, which
means it can do anything. (The standard joke here is that it can
legally make demons fly out your nose.) One of the infinitely many
possible behaviors is that it can behave "correctly".

Once you've determined that your code invokes undefined behavior,
there's usually no point in worrying about why it behaves in a
particular way. Just fix the code.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Niklas Norrthon
Guest
Posts: n/a
 
      10-13-2005
(E-Mail Removed) writes:

> sorry about the posting thing, i hadnt realized...
> hope this is the correct way...
>
> Now It's killing me! Why does it crash on the Fifth element!
> why not first?! or after a lot?!


That's the way undefined behavior in C works. It might even not
crash at all, or it might crash only when your boss is looking,
or it might format your hard drive.

The C language defines how a compiled program should behave, and
it defines some boundaries your code may not cross. Usually there
are no checks neither at compile time nor run time that those
boundaries are not crossed. But after they are crossed absolutly
anything could happen according to the standard.

One of those boundaries is memory. The standard say you may
use memory you own, and you must not use memory you don't own.

In the real world with "normal" platforms (Unix, Windows, Mac
et cetera), undefined behavior usally leads to some pretty
predictable behavior, when you are familiar with the
implementation.

For example, when you start a program on a typical 32 bit unix
(or windows) platform that program (or process actually) has its
own 4 GB "virtual" address starting at 0x00000000 and ending at
0xFFFFFFFF. The operating system maps some of those virtual
addresses to physical memory, and some addresses are not mapped
at all. Several processes running simultaniously could have
a mapping for the same virtual address, but then it would map
to different physical locations. (All this is handled by the
operating system, and is usually nothing a programmer would have
to care about). This means that it is pretty hard for a C program
to write data into memory owned by another running process. So in
theory undefined behavior could lead to another unrelated process
to crash, that is quite unlikely to happen.

By the way, what does "crash" mean? In unix, sometimes a process
suddenly writes a message to stderr saying something like:
"segmentation fault", writes a file named "core" somewhere and
then disappears entirely from the face of earth. (in windows
a message dialog pops up instead, saying "access violation..."). Where
does that message come from? It is unlikely that are any statements
like fprintf(stderr, "segmentation fault\n"); in the programs
source code. The answer is that it was the operating system which
aborted the program and wrote the message (or showed the message
dialog). "Segmentation fault" usally means that the process tried
to read from or write to memory a virtual memory address that
either was not mapped to any physical address, or mapped to
an address which was protected from that kind of access (executable
code is usally read-only for example).

The memory for a running process could be organized like this:
+-----------------------------------+
| | 0xFFFFFFFF
| |
| |
| |
| Unmapped memory addresses |
| |
| |
| |
| |
+-----------------------------------+
| |
| |
| |
| |
| Mapped memory addresses |
| |
| |
| |
| |
| |
| |
| |
| |
+-----------------------------------+
| |
| |
| Unmapped memory addresses |
| |
| |
| | 0x00000000
+-----------------------------------+

A program trying to read or write to an unmapped memory address
invokes undefined behavior, and anything *could* happen, but
in reallity a pretty predictable "crash" is the result.

But the C language standard does not say: "You may not write
to unmapped addresses". It says that you may not write to memory
not "owned" or "allocated" by the program. All unmapped memory
is also not owned by the program, but also a large portion
of the mapped memory is not owned by the program. A read or
write operation to this memory is still undefined behavior, but
is much less likely to be caught by the operating system, so usually
the result is that nothing "unexpected" will happen at the very
momement of the read or write operation, but it is quite likely
that some data needed later gets destroyed, resulting in a "crash"
later (when the boss looks over your shoulder).

The following program invokes undefined behavior:

/* undef.c */
#include <stdio.h>

int main(void)
{
int i;
int array[2];

for (i = 0; i < 4; ++i) {
printf("i = %d\n", i);
array[i] = 0;
}

printf("The end!\n");
return 0;
}

It writes a zero to element 0-3 of 'array' which only has elements
0-1. The output from my system is (it could be something else on your):

% gcc undef.c -o undef
% ./undef
i = 0
i = 1
i = 2
i = 3
i = 1
i = 2
i = 3
i = 1
i = 2
i = 3

Oops its looping. The entire logic of my program changed as a result
of writing past the end of an array. In this case array[3] happened
to be the same thing as i.

Below is an example of how the mapped memory of a process might be
organized.

+-----------------------------------+
| |
| Program stack |
| (function return addresses, |
| local variables and |
| function arguments |
| |
+-----------------------------------+
| |
| |
| Unused |
| |
| |
+-----------------------------------+
| |
| Free store |
| (also known as "heap") |
| This is where the malloc family |
| of function gets its memory. |
| |
| |
+-----------------------------------+
| |
| Executable code |
| main(), printf()... |
| |
+-----------------------------------+
| |
| Initialized data |
| (globals, local static, |
| string literals...) |
| |
+-----------------------------------+

The C standard says nothing of how memory should be organized,
but the scheme above is very common. The order of the different
sections might change between platforms and operating systems,
and there might be some additional sections, but except for
DS9000 and similar platform the above is in priniple true.

The impact of this is that it is pretty easy to predict what will
happen when a program uses memory illegally:

Writing out of bounds of a global array will modify another
global variable. Writing data to a function pointer will immediatly
crash the program (os protection of read-only memory). Writing
out of bounds of a dynamically allocated array will either corrupt
the free store or change the value of another dynamically allocated
variable. And finally writing out of bounds of a local variable
will either change the value of another local variable or corrupt
the call stack.

The worst error (in the meaning most difficult to debug) of these
errors, according to my experience, is corrupting the free store.
The reason is that the system (malloc family of functions) stores
book-keeping data (like the size of allocated arrays, and location
of freed arrays) together with the dynamically allocated variables,
and corrupting such data might lead to a program crash much much
much later in the program execution, in a totally unrelated part
of the program.

Hope the above rambling was of some help for someone, and not
considered too off topic by the rest...

/Niklas Norrthon
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
JNI:Solaris 9-Signal 11 in realloc() Mr T Java 0 11-19-2003 10:22 AM
Realloc a struct ** Henrik J C++ 1 11-10-2003 08:54 AM
Problem with malloc, realloc, _msize and memcpy Bren C++ 8 09-03-2003 11:01 PM
g++ 3.2.2 realloc bug? Jonathan.Bailleul C++ 3 08-08-2003 06:16 PM
Impossible Leak realloc Eitan Michaelson C++ 11 06-30-2003 10:33 AM



Advertisments