Thread: realloc() troubles

  1. #1
    Registered User
    Join Date
    Nov 2005
    Posts
    145

    realloc() troubles

    Hi, I seem to be having a lot of problems with realloc, I have some int arrays, which I'm storing values in, I'm initially declaring there size using malloc, later on in the program I need to add more elements, one at a time to the array, so i do

    Code:
     test = realloc(test,no_of_elements*4)
    When I then print out these arrays, it prints out elements as numbers like
    Code:
    4007400
    yet I'm only dealing with single digit numbers

    If I comment out the realloc statements, and just add the elements anyway ignoring the fact I'm adding in elements out of bounds, then the output is printed out fine. Obviouslt I cannot leave it like this though as I'm out of bounds and that's unsafe.

    I'm checking to see if realloc returns NULL whenever it is called, but it never does.

    What is likely to cause this problem?

    Thanks for any advice
    Last edited by Wiretron; 12-24-2006 at 06:08 PM.

  2. #2
    Registered User
    Join Date
    Nov 2005
    Posts
    145
    The only think I can think of which may be of relevance is that...

    I'm declaring each array using

    Code:
    int *test=NULL;
    test = (int *) malloc((x)*4);
    and then passing it to a function which fills it with elemnts which works fine. Now I need to add another element for whatever reason, so I do...

    Code:
    add_element(test)
    which goes to...

    Code:
    int add_element(int *test){
    test = realloc(test,(x+1)*4);
    test[x] = 7;
    return 0;
    }
    Is it possible that the problem is to do with the way I'm passing the int array around?

  3. #3
    Fear the Reaper...
    Join Date
    Aug 2005
    Location
    Toronto, Ontario, Canada
    Posts
    625
    I think showing us a little code is the next step.

    A few things I noticed that you may want to fix, however.

    1) This is no real biggie, but it's usually good practice not to cast malloc.
    2) All those 4's you put in there should be replaced by sizeof(int) . That one's important.
    Teacher: "You connect with Internet Explorer, but what is your browser? You know, Yahoo, Webcrawler...?" It's great to see the educational system moving in the right direction

  4. #4
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    Code:
    int add_element(int *test){
    test = realloc(test,(x+1)*4);
    test[x] = 7;
    return 0;
    }
    Won't work at all. First, never assign back to the same variable when using realloc(). (ie, b = realloc(a, size) is ok, but not a = realloc(a, size)) If realloc were to fail, it will not touch your previously allocated memory. So if it fails, you need to old pointer around to free it. Something like:
    Code:
    int *test = pointer to some memory...
    int *temp;
    temp = realloc(test, sizeof(int) * newsize);
    if(!temp)
    {
      // Realloc failed! Panic, or something, but remember:
      // test is still valid, and still must be free'd sometime.
    }
    // Realloc is ok.
    test = temp;
    Next, bigger problem: Suppose that in your original function, realloc() succeeds, but has to move your data to a different location to accomated the larger size. test's value has changed, however, you do not return this value to the caller, and your program is likely to segfault somewhere down the road. (A nasty bug to find...)
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    If you must change an object, pass a pointer to the object:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define MIN_SIZE        10U
    
    int *append( int *parray[], size_t size, int anynum );
    
    int main(void) {
       int *test = malloc(MIN_SIZE * sizeof *test);
       if (test) {
          int fill;
          for (fill = 0; fill < MIN_SIZE; ++fill) {
             test[fill] = fill + 1;
          }
          /*
          ** Checking appends return value to make sure that everything worked
          */
          if (append(&test, MIN_SIZE, 11) != NULL) {
             printf("Success :)\n");
          }
          else {
             printf("Failure :(\n");
          }
    
          free(test);
       }
       else {
         perror("malloc");
       }
    
       return 0;
    }
    
    int *append( int *parray[], size_t size, int anynum ) {
       int *newarray = realloc(*parray, size + 1U);
       if (newarray) {
          *parray = newarray;
          (*parray)[size] = anynum;
       }
       else {
          free(newarray);
          newarray = NULL;
       }
    
       return newarray;
    }
    Last edited by whiteflags; 12-24-2006 at 11:57 PM.

  6. #6
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Code:
       else {
          free(newarray);
          newarray = NULL;
       }
    makes no harm, but has no meaning also - newarray is already NULL in the else
    So this part can be freely skipped
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    > So this part can be freely skipped
    I prefer not to, in order to ensure that I return something in all cases and in prevention of possible memory leaks.

  8. #8
    Registered User
    Join Date
    Nov 2005
    Posts
    145
    Oh ok, so is the problem mainly to do with me not passing back the new pointer once I've realloced?

    Also in the above example, why is append first mentioned at the top above int main()?

  9. #9
    Registered User
    Join Date
    Nov 2005
    Posts
    145
    Quote Originally Posted by citizen
    If you must change an object, pass a pointer to the object:
    I tried out your code, and added in a loop which prints out test at the end, and I'm getting the output:

    1 2 3 4 196724 6 3999000 3999000 9 10

    Do you know why there is still wierd output in there?

  10. #10
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by Wiretron
    Also in the above example, why is append first mentioned at the top above int main()?
    It is function declaration. It describes the function prototype for the compiler.
    It is needed because the function body is located after the function call.
    So when compiler comes to the line where the function is called it does not know about this function nothing.

    To give to compiler some knowledge about the function - function declaration is provided before actual call.


    I tried out your code, and added in a loop which prints out test at the end, and I'm getting the output:
    Could you post your code?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    @ citizen
    > else
    > free(newarray);
    Except if realloc fails, then newarray will be NULL anyway.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    Nov 2005
    Posts
    145
    There is far too much code to post, I posted the main bits of the program which are relevant. Here is citizens code which I modified slightly and prints out wierd output:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define MIN_SIZE        10U
    
    int *append( int *parray[], size_t size, int anynum );
    
    int main(void) {
        int i = 0;
       int *test = malloc(MIN_SIZE * sizeof *test);
       if (test) {
          int fill;
          for (fill = 0; fill < MIN_SIZE; ++fill) {
             test[fill] = fill + 1;
          }
          /*
          ** Checking appends return value to make sure that everything worked
          */
          if (append(&test, MIN_SIZE, 11) != NULL) {
             
          }
          else {
             printf("Failure :(\n");
          }
          for(i=0;i<fill;i++){
                                 printf("%d ",test[i]);
                                 }
          free(test);
       }
       else {
         perror("malloc");
       }
       
    
       return 0;
    }
    
    int *append( int *parray[], size_t size, int anynum ) {
       int *newarray = realloc(*parray, size + 1U);
       if (newarray) {
          *parray = newarray;
          (*parray)[size] = anynum;
       }
       else {
          free(newarray);
          newarray = NULL;
       }
    
       return newarray;
    }

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > int *newarray = realloc(*parray, size + 1U);
    You still need the multiplier for the size

    int *newarray = realloc(*parray, (size + 1U) * sizeof *newarray );
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  14. #14
    Registered User
    Join Date
    Nov 2005
    Posts
    145
    Ok I have got citizens example working, now say I want to print out test in a seperate function, I've called it from within main using:

    Code:
    print(&test,fill);
    which runs the function:

    Code:
    int *print(int *test[],int fill){
        int i = 0;
        for(i=0;i<fill;i++){
                            printf("%d ",test[i]);
                            }
                            return 0;
    }
    Yet this prints outs the wierd output again, can anyone see what's going wrong?

    If I change the print statement to

    Code:
    printf("%d ",*test[i]);
    then it just crashes
    Last edited by Wiretron; 12-25-2006 at 05:52 AM.

  15. #15
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    print(test,fill); maybe?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. did i understood right this explantion of realloc..
    By transgalactic2 in forum C Programming
    Replies: 3
    Last Post: 10-24-2008, 07:26 AM
  2. writing a pack-style function, any advices?
    By isaac_s in forum C Programming
    Replies: 10
    Last Post: 07-08-2006, 08:09 PM
  3. using realloc
    By bobthebullet990 in forum C Programming
    Replies: 14
    Last Post: 12-06-2005, 05:00 PM
  4. segfault on realloc
    By ziel in forum C Programming
    Replies: 5
    Last Post: 03-16-2003, 04:40 PM
  5. Realloc inappropriate for aligned blocks - Alternatives?
    By zeckensack in forum C Programming
    Replies: 2
    Last Post: 03-20-2002, 02:10 PM