Realloc destroys?

Discussion in 'C Programming' started by ifmusic@gmail.com, Oct 10, 2005.

  1. Guest

    I used to think that i knew to program in C but this problem is making
    me thing otherwise.
    i'm trying to do something trivial, i suppose.
    i have this struct:

    typedef struct{
    int socket;
    char ip[16];
    }peers;

    in a main() i malloc this way:
    Peers=malloc(sizeof(peers));
    Then, my program would eventually want to save more "peers" so
    i said, why dont i Realloc this thing x2 x3 x4 x5 and so on.. as
    needed. So i created this function:

    peers* ingresaripsock(peers* lista,int sock, char ip[16],int *tm)
    {
    int offset= (*tm)++;

    if (offset>0) lista = realloc(lista,offset * sizeof(peers)+1);

    strcpy((lista + offset)->ip, ip);
    (lista + offset)-> socket=sock;

    return lista;
    }

    i print the results with:

    void imprimirpeers(peers* lista, int tm){
    int i=0;

    for(i=0;i<tm;i++){
    printf("Ip: %s - Sock: %d\n",(lista + i) ->ip , (lista + i)
    ->socket);
    }
    }


    but when i printf the Results, it's all weird data. I believe the
    problem is around the Realloc becuase i tried this code but instead of
    using realloc i malloc'd from the first time with space for like 20
    positions (commented the realloc part in the function) and it worked
    just fine. But i want to use what i Really need, dont want to do malloc
    ( 20000000) and use a couple of bytes...


    Please i really need some help-
    , Oct 10, 2005
    #1
    1. Advertising

  2. wrote:

    > if (offset>0) lista = realloc(lista,offset * sizeof(peers)+1);


    This is a severe mistake. Never use the form
    ptr = realloc(ptr, size);
    Instead have the results of the realloc() assigned to a temporary
    variable to give you at least the option of what to do if realloc fails.
    Martin Ambuhl, Oct 10, 2005
    #2
    1. Advertising

  3. Guest

    yes, after writing the post, i read some of that, i'm switchin to a
    pointer to pointer data structure. hope it works that way.
    Thanks.
    , Oct 10, 2005
    #3
  4. In article <>,
    wrote:

    > I used to think that i knew to program in C but this problem is making
    > me thing otherwise.
    > i'm trying to do something trivial, i suppose.
    > i have this struct:
    >
    > typedef struct{
    > int socket;
    > char ip[16];
    > }peers;
    >
    > in a main() i malloc this way:
    > Peers=malloc(sizeof(peers));
    > Then, my program would eventually want to save more "peers" so
    > i said, why dont i Realloc this thing x2 x3 x4 x5 and so on.. as
    > needed. So i created this function:
    >
    > peers* ingresaripsock(peers* lista,int sock, char ip[16],int *tm)
    > {
    > int offset= (*tm)++;
    >
    > if (offset>0) lista = realloc(lista,offset * sizeof(peers)+1);


    Your calculation how many bytes are needed looks interesting.
    Christian Bau, Oct 11, 2005
    #4
  5. On 10 Oct 2005 14:06:47 -0700, wrote:

    >I used to think that i knew to program in C but this problem is making
    >me thing otherwise.
    >i'm trying to do something trivial, i suppose.
    >i have this struct:
    >
    >typedef struct{
    >int socket;
    >char ip[16];
    >}peers;
    >
    >in a main() i malloc this way:
    >Peers=malloc(sizeof(peers));
    >Then, my program would eventually want to save more "peers" so
    >i said, why dont i Realloc this thing x2 x3 x4 x5 and so on.. as
    >needed. So i created this function:
    >
    >peers* ingresaripsock(peers* lista,int sock, char ip[16],int *tm)


    Is *tm a count of how may structures your currently have space for?

    >{
    >int offset= (*tm)++;


    offset is the original value of *tm.

    >
    >if (offset>0) lista = realloc(lista,offset * sizeof(peers)+1);


    What did you think the +1 does. What you have done, if realloc
    succeeds, is allocate space for the same number of structures plus one
    more byte. You did not allocate space for an extra struct. Did you
    really mean
    ... = realloc(lista, (offset+1) * sizeof(peers));

    >
    >strcpy((lista + offset)->ip, ip);


    As it stands now, this invokes undefined behavior. lista points to an
    allocated area capable of holding offset structures. The structures
    are numbered 0, 1, ..., offset-1. You are now writing beyond the end
    of your allocated area.

    >(lista + offset)-> socket=sock;
    >
    >return lista;
    >}
    >
    >i print the results with:
    >
    >void imprimirpeers(peers* lista, int tm){
    >int i=0;
    >
    >for(i=0;i<tm;i++){
    > printf("Ip: %s - Sock: %d\n",(lista + i) ->ip , (lista + i)
    >->socket);
    > }
    >}
    >
    >
    >but when i printf the Results, it's all weird data. I believe the
    >problem is around the Realloc becuase i tried this code but instead of
    >using realloc i malloc'd from the first time with space for like 20
    >positions (commented the realloc part in the function) and it worked
    >just fine. But i want to use what i Really need, dont want to do malloc
    >( 20000000) and use a couple of bytes...
    >
    >
    >Please i really need some help-



    <<Remove the del for email>>
    Barry Schwarz, Oct 11, 2005
    #5
  6. Guest

    Thank you all for all the feedback,
    now i have a pointer to pointer structure.

    typedef struct{
    int socket;
    char id[16];
    }reqs;

    reqs** ingresaridsock(reqs** lista,int sock, char id[16],int *tm){
    int i;
    reqs* aux;
    reqs **temp;
    int offset= (*tm)++;
    aux = malloc(sizeof(reqs));
    if (offset > 0 ){
    if ((temp = realloc(lista, (offset+1) * sizeof(*lista)))==NULL)
    exit(1);
    lista=temp;}
    strcpy(aux->id, id);
    aux->socket= sock;
    lista[offset]= aux;
    return lista;

    Now, it seems to work just fine. BUT!, i add 1,2,3,4 and on the fifth
    item,
    i get Segmentation Fault! Knowing that i'm not freeing memory as i
    should
    shouldn't it be possible to store more than 4 miserable items without
    freeing?!.

    thanks again.

    Barry Schwarz ha escrito:

    > On 10 Oct 2005 14:06:47 -0700, wrote:
    >
    > >I used to think that i knew to program in C but this problem is making
    > >me thing otherwise.
    > >i'm trying to do something trivial, i suppose.
    > >i have this struct:
    > >
    > >typedef struct{
    > >int socket;
    > >char ip[16];
    > >}peers;
    > >
    > >in a main() i malloc this way:
    > >Peers=malloc(sizeof(peers));
    > >Then, my program would eventually want to save more "peers" so
    > >i said, why dont i Realloc this thing x2 x3 x4 x5 and so on.. as
    > >needed. So i created this function:
    > >
    > >peers* ingresaripsock(peers* lista,int sock, char ip[16],int *tm)

    >
    > Is *tm a count of how may structures your currently have space for?
    >
    > >{
    > >int offset= (*tm)++;

    >
    > offset is the original value of *tm.
    >
    > >
    > >if (offset>0) lista = realloc(lista,offset * sizeof(peers)+1);

    >
    > What did you think the +1 does. What you have done, if realloc
    > succeeds, is allocate space for the same number of structures plus one
    > more byte. You did not allocate space for an extra struct. Did you
    > really mean
    > ... = realloc(lista, (offset+1) * sizeof(peers));
    >
    > >
    > >strcpy((lista + offset)->ip, ip);

    >
    > As it stands now, this invokes undefined behavior. lista points to an
    > allocated area capable of holding offset structures. The structures
    > are numbered 0, 1, ..., offset-1. You are now writing beyond the end
    > of your allocated area.
    >
    > >(lista + offset)-> socket=sock;
    > >
    > >return lista;
    > >}
    > >
    > >i print the results with:
    > >
    > >void imprimirpeers(peers* lista, int tm){
    > >int i=0;
    > >
    > >for(i=0;i<tm;i++){
    > > printf("Ip: %s - Sock: %d\n",(lista + i) ->ip , (lista + i)
    > >->socket);
    > > }
    > >}
    > >
    > >
    > >but when i printf the Results, it's all weird data. I believe the
    > >problem is around the Realloc becuase i tried this code but instead of
    > >using realloc i malloc'd from the first time with space for like 20
    > >positions (commented the realloc part in the function) and it worked
    > >just fine. But i want to use what i Really need, dont want to do malloc
    > >( 20000000) and use a couple of bytes...
    > >
    > >
    > >Please i really need some help-

    >
    >
    > <<Remove the del for email>>
    , Oct 11, 2005
    #6
  7. Guest

    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?!.

    ha escrito:

    > Thank you all for all the feedback,
    > now i have a pointer to pointer structure.
    >
    > typedef struct{
    > int socket;
    > char id[16];
    > }reqs;
    >
    > reqs** ingresaridsock(reqs** lista,int sock, char id[16],int *tm){
    > int i;
    > reqs* aux;
    > reqs **temp;
    > int offset= (*tm)++;
    > aux = malloc(sizeof(reqs));
    > if (offset > 0 ){
    > if ((temp = realloc(lista, (offset+1) * sizeof(*lista)))==NULL)
    > exit(1);
    > lista=temp;}
    > strcpy(aux->id, id);
    > aux->socket= sock;
    > lista[offset]= aux;
    > return lista;
    >
    > Now, it seems to work just fine. BUT!, i add 1,2,3,4 and on the fifth
    > item,
    > i get Segmentation Fault! Knowing that i'm not freeing memory as i
    > should
    > shouldn't it be possible to store more than 4 miserable items without
    > freeing?!.
    >
    > thanks again.
    >
    > Barry Schwarz ha escrito:
    >
    > > On 10 Oct 2005 14:06:47 -0700, wrote:
    > >
    > > >I used to think that i knew to program in C but this problem is making
    > > >me thing otherwise.
    > > >i'm trying to do something trivial, i suppose.
    > > >i have this struct:
    > > >
    > > >typedef struct{
    > > >int socket;
    > > >char ip[16];
    > > >}peers;
    > > >
    > > >in a main() i malloc this way:
    > > >Peers=malloc(sizeof(peers));
    > > >Then, my program would eventually want to save more "peers" so
    > > >i said, why dont i Realloc this thing x2 x3 x4 x5 and so on.. as
    > > >needed. So i created this function:
    > > >
    > > >peers* ingresaripsock(peers* lista,int sock, char ip[16],int *tm)

    > >
    > > Is *tm a count of how may structures your currently have space for?
    > >
    > > >{
    > > >int offset= (*tm)++;

    > >
    > > offset is the original value of *tm.
    > >
    > > >
    > > >if (offset>0) lista = realloc(lista,offset * sizeof(peers)+1);

    > >
    > > What did you think the +1 does. What you have done, if realloc
    > > succeeds, is allocate space for the same number of structures plus one
    > > more byte. You did not allocate space for an extra struct. Did you
    > > really mean
    > > ... = realloc(lista, (offset+1) * sizeof(peers));
    > >
    > > >
    > > >strcpy((lista + offset)->ip, ip);

    > >
    > > As it stands now, this invokes undefined behavior. lista points to an
    > > allocated area capable of holding offset structures. The structures
    > > are numbered 0, 1, ..., offset-1. You are now writing beyond the end
    > > of your allocated area.
    > >
    > > >(lista + offset)-> socket=sock;
    > > >
    > > >return lista;
    > > >}
    > > >
    > > >i print the results with:
    > > >
    > > >void imprimirpeers(peers* lista, int tm){
    > > >int i=0;
    > > >
    > > >for(i=0;i<tm;i++){
    > > > printf("Ip: %s - Sock: %d\n",(lista + i) ->ip , (lista + i)
    > > >->socket);
    > > > }
    > > >}
    > > >
    > > >
    > > >but when i printf the Results, it's all weird data. I believe the
    > > >problem is around the Realloc becuase i tried this code but instead of
    > > >using realloc i malloc'd from the first time with space for like 20
    > > >positions (commented the realloc part in the function) and it worked
    > > >just fine. But i want to use what i Really need, dont want to do malloc
    > > >( 20000000) and use a couple of bytes...
    > > >
    > > >
    > > >Please i really need some help-

    > >
    > >
    > > <<Remove the del for email>>
    , Oct 11, 2005
    #7
  8. Old Wolf Guest

    wrote:
    >
    > typedef struct{
    > int socket;
    > char id[16];
    > }reqs;
    >
    > reqs** ingresaridsock(reqs** lista,int sock, char id[16],int *tm){
    > int i;
    > reqs* aux;
    > reqs **temp;
    > int offset= (*tm)++;
    > aux = malloc(sizeof(reqs));
    > if (offset > 0 ){
    > if ((temp = realloc(lista, (offset+1) * sizeof(*lista)))==NULL)
    > exit(1);
    > lista=temp;}


    You never allocate anything when *tm was 0.
    If lista were NULL (or an array of size 0), then you would
    cause undefined behaviour.

    > strcpy(aux->id, id);
    > aux->socket= sock;
    > lista[offset]= aux;
    > return lista;
    >
    > Now, it seems to work just fine. BUT!, i add 1,2,3,4 and on the
    > fifth item, i get Segmentation Fault!


    If the above was not the problem, then perhaps you have a buffer
    overflow in the strcpy, or some other heap corruption. Can you
    post a complete, compilable program that demonstrates the problem?

    BTW, please don't top-post ( http://en.wikipedia.org/wiki/Top-posting )
    Old Wolf, Oct 11, 2005
    #8
  9. Guest

    There's no problem about the tm being 0.

    the thing with posting the whole thing is that i don't know how you're
    gonna test it. I'm testing it with 3 vmwares as clients and 1 vmware as
    server which is storing the info.

    Again, something that's still bugging me is the "endless" list i'm
    getting...

    if you want i can mail you the code.

    Thanks for the help-
    , Oct 11, 2005
    #9
  10. On 10 Oct 2005 18:11:39 -0700, wrote:

    >Thank you all for all the feedback,
    >now i have a pointer to pointer structure.
    >
    >typedef struct{
    >int socket;
    >char id[16];
    >}reqs;
    >
    >reqs** ingresaridsock(reqs** lista,int sock, char id[16],int *tm){
    >int i;
    >reqs* aux;
    >reqs **temp;
    >int offset= (*tm)++;
    >aux = malloc(sizeof(reqs));
    >if (offset > 0 ){
    > if ((temp = realloc(lista, (offset+1) * sizeof(*lista)))==NULL)
    >exit(1);
    > lista=temp;}
    >strcpy(aux->id, id);
    >aux->socket= sock;
    >lista[offset]= aux;
    >return lista;
    >
    >Now, it seems to work just fine. BUT!, i add 1,2,3,4 and on the fifth
    >item,
    >i get Segmentation Fault! Knowing that i'm not freeing memory as i
    >should
    >shouldn't it be possible to store more than 4 miserable items without
    >freeing?!.


    On which statement does the seg fault occur?

    How are you calling this function? Show us main.


    <<Remove the del for email>>
    Barry Schwarz, Oct 11, 2005
    #10
  11. Marc Thrun Guest

    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?!.
    >
    > 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.
    Marc Thrun, Oct 11, 2005
    #11
  12. Guest

    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.
    , Oct 12, 2005
    #12
  13. Guest

    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.
    , Oct 12, 2005
    #13
  14. 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) <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.
    Keith Thompson, Oct 12, 2005
    #14
  15. Guest

    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:

    > 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) <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.
    , Oct 12, 2005
    #15
  16. Guest

    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:

    > 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) <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.
    , Oct 12, 2005
    #16
  17. Default User Guest

    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
    Default User, Oct 12, 2005
    #17
  18. 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) <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.
    Keith Thompson, Oct 12, 2005
    #18
  19. 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 = 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
    Niklas Norrthon, Oct 13, 2005
    #19
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    6
    Views:
    525
    Brendan Reynolds
    Jun 30, 2005
  2. Stefan Kuhr
    Replies:
    2
    Views:
    573
    Stefan Kuhr
    Nov 21, 2006
  3. Replies:
    2
    Views:
    745
  4. Eric Sosman

    pointer suddenly destroys

    Eric Sosman, Nov 25, 2005, in forum: C Programming
    Replies:
    3
    Views:
    300
    Roman Mashak
    Nov 26, 2005
  5. Adrienne Boswell

    Re: Client Destroys My Validated HTML

    Adrienne Boswell, Jul 31, 2008, in forum: HTML
    Replies:
    0
    Views:
    369
    Adrienne Boswell
    Jul 31, 2008
Loading...

Share This Page