Thread: realloc misuse

  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    486

    realloc misuse

    Hey,

    I have a function that uses a 2D array of doubles that needs to be reallocated every now and again as the input size changes with time. This is the function. The first time this function is called, particleMatrix is NULL (ei, I use it like malloc on the first call)

    Code:
    int readTimeStep(FILE *input, double **particleMatrix)
    {
      int i,N;
      double time;
    
     fscanf(input,"%d",&N);
     fscanf(input,"%*s %*s %*d %*s %*s %*s %*s %*s %*s %*s %*s %lf",&time);
     
      /// 
      particleMatrix = (double**) realloc(particleMatrix, N * sizeof(double*));
      if (particleMatrix == NULL)
      {
        printf("error allocating memory for particleMatrix");
        abort();
      }
      for (i = 0; i < N; i++)
      {
        particleMatrix[i] = (double *) realloc(particleMatrix[i], 4 * (sizeof(double)));
        if (particleMatrix[i] == NULL)
        {
          printf("error allocating memory for particleMatrix[i]");
          abort();
        }
      }  
      ///
      for (i = 0; i < N && fscanf(input,"%*s %lf %lf %lf %lf",&particleMatrix[i][0],&particleMatrix[i][1],&particleMatrix[i][2],&particleMatrix[i][3]) != EOF; i++)
      {
        ;
      }
    
     return time; //reallocate matrix for each N during loop
    }
    When I run this, I get:

    Code:
    *** glibc detected *** ./chargestate: realloc(): invalid pointer: 0x0000000000400f73 ***
    What am I doing wrong?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    One thing that comes to mind is that you are assigning to the parameter in the function. If you intend the changes to the parameter to be reflected in the caller, you should pass a pointer to it. Have you considered defining a struct for particleMatrix?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    particleMatrix is declared in the caller - the realloc in this function should be reflected in the caller, no? Or will realloc cause the caller to lose track of the pointer to the start of particleMatrix?

    I have never used a struct like that before. Do you mean something like a linked list?

    EDIT: putting this function inside the caller and getting rid of the call results in the same error
    Last edited by KBriggs; 06-08-2009 at 01:08 PM.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by KBriggs
    particleMatrix is declared in the caller - the realloc in this function should be reflected in the caller, no? Or will realloc cause the caller to lose track of the pointer to the start of particleMatrix?
    Consider the case where realloc() is unable to expand the block of memory in place, and has to allocate a new block and copy over. Without another level of indirection, the caller's pointer will continue to point to the old block of memory.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    I just fixed that. Now the code is:

    Code:
    double **readTimeStep(FILE *input, double **particleMatrix,int N)
    {
      int i;
    
      particleMatrix = (double**) realloc(particleMatrix, N * sizeof(double*));
      if (particleMatrix == NULL)
      {
        printf("error allocating memory for particleMatrix");
        abort();
      }
      for (i = 0; i < N; i++)
      {
        particleMatrix[i] = (double *) realloc(particleMatrix[i], 4 * (sizeof(double)));
        if (particleMatrix[i] == NULL)
        {
          printf("error allocating memory for particleMatrix[i]");
          abort();
        }
      }  
      ///
      for (i = 0; i < N && fscanf(input,"%*s %lf %lf %lf %lf",&particleMatrix[i][0],&particleMatrix[i][1],&particleMatrix[i][2],&particleMatrix[i][3]) != EOF; i++)
      {
        ;
      }
    
     return particleMatrix; //reallocate matrix for each N during loop
    }
    It gives the same error still... Rawr.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Did you #include <stdlib.h>?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    yeah I did

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Post the smallest and simplest program that demonstrates the error.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    This just segfaults, but most likely for the same reason...

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    double **readTimeStep(FILE *input, double **particleMatrix,int N)
    {
      int i;
    
      particleMatrix = (double**) realloc(particleMatrix, N * sizeof(double*));
      if (particleMatrix == NULL)
      {
        printf("error allocating memory for particleMatrix");
        abort();
      }
      for (i = 0; i < N; i++)
      {
        particleMatrix[i] = (double *) realloc(particleMatrix[i], 4 * (sizeof(double)));
        if (particleMatrix[i] == NULL)
        {
          printf("error allocating memory for particleMatrix[i]");
          abort();
        }
      }  
      ///
      for (i = 0; i < N && fscanf(input,"%*s %lf %lf %lf %lf",&particleMatrix[i][0],&particleMatrix[i][1],&particleMatrix[i][2],&particleMatrix[i][3]) != EOF; i++)
      {
        printf("%f\t%f\t%f\t%f\n",particleMatrix[i][0],particleMatrix[i][1],particleMatrix[i][2],particleMatrix[i][3]);
      }
    
     return particleMatrix; //reallocate matrix for each N during loop
    }
    
    int main()
    {
      double **particleMatrix;
      FILE *input;
      int N,i;
      double time;
      
      input = fopen("allbodys.xyz","r");
      if (input == NULL)
      {
        printf("input file open failed\n");
        abort();
      }
      fscanf(input,"%d",&N);
      fscanf(input,"%*s %*s %*d %*s %*s %*s %*s %*s %*s %*s %*s %lf",&time);
      particleMatrix = readTimeStep(input,particleMatrix,N);
      fclose(input);
      
      for (i = 0; i < N; i++)
      {
        free(particleMatrix[i]);
      }
      free(particleMatrix);
    }

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You did not initialise particleMatrix in the main function. It should be initialised to be a null pointer.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    Pretty sure NULL is the default no?

    How do i make it NULL?

    particleMatrix = NULL?

    EDIT:

    adding that line just makes the program segfault instead of giving me the big error backtrace. Which could be a good thing.
    Last edited by KBriggs; 06-08-2009 at 01:34 PM.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    the original particleMatrix is not set to NULL, so the first time you call realloc() it thinks that there is already some memory allocated - you are now in a place called "undefined behaviour land" - which is a strange place somewhat resembling the "improbability drive" in the Hitchhikers guide to the Galaxy series - anything can (and will) happen. Unfortunately, unlike the improbability drive, nothing good comes out of this place. Just weirdness and badness. In this case, it's likely that realloc decides to free the memory that wasn't allocated and it probably gives you the error message posted in that attempt.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    realloc() doesn't automatically initialize its memory to zero. So if N becomes bigger, you'll make particleMatrix bigger, but particleMatrix[something] .. particleMatrix[last] will be uninitialized. You'll then pass these uninitialized values to the second realloc(), and your program will crash.

    There are two ways to fix this:
    1. Simply initialize the newly realloc()'d memory to zero. (Not the best solution, but it works.)
    2. Use malloc() the second time around, and instead of looping with "for (i = 0; i < N; i++)", only loop over the elements you have newly allocated as the array became larger.


    I would second laserlight's opinion above and use something like this.
    Code:
    struct particleMatrixRow_t {
        double *col;
    };
    
    struct particleMatrix_t {
        struct particleMatrixRow_t *row;
        size_t rows, cols;
    };
    I'm assuming here that your matrix is square, so you can store one "cols" variable for the whole matrix. If this is not the case, simply store the cols in the particleMatrixRow_t structure.

    This has several advantages:
    • It's easy to pass around a structure.
    • You know how much memory was previously allocated, so you know which parts of the structure are new, so you know which parts need malloc()ing.
    • It's a lot more easily expandable.


    [edit] Wow. There were about eight replies while I was typing up this one! I think this post is still applicable, though, so I'll leave it be. [/edit]
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by KBriggs
    Pretty sure NULL is the default no?
    No, if you did not initialise, you did not initialise.

    Quote Originally Posted by KBriggs
    How do i make it NULL?

    particleMatrix = NULL?
    Yes, you should initialise it using a null pointer constant like NULL.

    EDIT:
    dwks' has a point: you would then have the same problem, but with the inner pointers.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    With my compiler, the output for this code is "yes." Doesn't that mean that NULL is the default already?

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
      double **particleMatrix;
      
      if (particleMatrix == NULL)
      {
        printf("yes\n");
      }
      else 
      {
        printf("no\n");
      }
    }

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