Thread: Problem with realloc() using on array of double

  1. #1
    Registered User
    Join Date
    Nov 2013
    Posts
    4

    Problem with realloc() using on array of double

    In my program I use structure
    Code:
    typedef struct {
      double *wc;
      double u, v, T;
      double k, om;
      int *ic; 
      int no_ngh_cells; 
    } NODE_DATA;
    I use array of NODE_DATA allocated with malloc().
    Code:
    NODE_DATA *ND = (NODE_DATA*)malloc(sizeof(NODE_DATA) * size);
    Then further in my program I determine the number N which means the size of wc[] and ic[].
    Every time N changes I reallocate arrays wc[] and ic[] in the following way

    Code:
    N = 0; //initial size
    ND[i].ic = (int*)malloc(sizeof(int));
    ND[i].wc = (double*)malloc(sizeof(double));
    ...
    N++; //if I detect increase of N
    ND[i].ic = (int*)realloc(ND[i].ic, N*sizeof(int));
    ND[i].wc = (double*)realloc(ND[i].wc, N*sizeof(double));
    The problem is that I can do it (program runs without error) only for ic[], while for wc[] it works only if I use (N+1) instead of N
    Code:
    ND[i].wc = (double*)realloc(ND[i].wc, (N+1) * sizeof(double));
    If I change array wc[] from double to float, i works fine with N, not (N+1), the same holds if I change it to int ...

    Error message is as follows in case of double *wc ...
    run: malloc.c:2373: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 *(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.
    Aborted (core dumped)

    Please, could someone explain where is the reason of it?
    Last edited by Vladimír Hric; 10-29-2015 at 04:27 PM. Reason: correction

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,662
    You're not allocating enough memory.

    > ND[i].wc = (double*)realloc((N+1), sizeof(double));
    This is correct if you're trying to use ND[N] at some point in the code.

    > If I change array wc[] from double to float, i works fine with N, not (N+1), the same holds if I change it to int ...
    This usually means you're just being lucky (or unlucky).

    > ND[i].ic = (int*)realloc(N, sizeof(int));
    You do know that realloc takes a parameter which is the OLD pointer.

    I'd be shocked if this compiled without any compilation warnings.
    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.

  3. #3
    Registered User
    Join Date
    Nov 2013
    Posts
    4
    Thank you for reply. I made some errors in the post, but not in my program. I compiled it with 0 errors/warnings in CodeBlocks IDE. I do not use ND[N], N concerns wc[] and ic[] only.
    Last edited by Vladimír Hric; 10-29-2015 at 04:30 PM.

  4. #4
    Registered User
    Join Date
    Nov 2013
    Posts
    4
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct {
      double u, v, T;
      double *wc
      int *ic; 
      int no_ngh_cells;
    } NODE_DATA;
    
    void alloc(NODE_DATA *ND, int c);
    
    int main() {
      int c = 25000;
      NODE_DATA *ND;
      ND = malloc(c*sizeof(NODE_DATA));
      alloc_test(ND, c);
      return 0;
    }
    
    void alloc_test(NODE_DATA *ND, int c) {
      int m = 10;
      int i, j, k;
      for (i = 0; i < c; i++) {
        ND[i].ic = malloc(sizeof(int));
        ND[i].wc = malloc(sizeof(double));
        k = 0;
        for (j = 0; j < m; j++) {
          k++;
          ND[i].ic = realloc(ND[i].ic, k*sizeof(int));
          ND[i].wc = realloc(ND[i].wc, k*sizeof(double));
         }
      }
    }
    This works. Compiled with gcc -Wall -pedantic test.c -o run ... but not in my larger program ...
    Last edited by Vladimír Hric; 10-29-2015 at 04:32 PM.

  5. #5
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Well, what's different in your larger program?

    Is the above a "test case"?

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,662
    > This works. Compiled with gcc -Wall -pedantic test.c -o run ... but not in my larger program ...
    I see the realloc calls changed into what they should be.

    It's no surprise really that it works, because you never use the memory you allocate.
    The point of the exercise would be to strip down a copy of your current program until you have something small, which still has the problem.
    It does however leak memory at an alarming rate.

    The problem you have is caused by memory corruption, which means you wrote past the end of some of the allocated memory and trashed the control block just beyond the end of the allocation.
    What you need is this -> Valgrind Home

    Compile your program with the -g option to get debug symbols.
    Run valgrind with the --db-attach option (read the manual) and your program name.
    The moment the program accesses out of bound memory, valgrind will prompt you to enter the debugger to help you locate and fix the problem.
    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.

  7. #7
    Registered User
    Join Date
    Sep 2014
    Posts
    364
    Please hold in mind that malloc, calloc and realloc can fail and return NULL.
    Therefor you should allways check the returned value of malloc, calloc and realloc.

    In case of realloc the old pointer is still valid.
    Code:
    …
        ND[i].ic = realloc(ND[i].ic, k*sizeof(int));
    …
    If realloc fails here, ND[i].ic will point to NULL, and the old pointer is valid, but where is the old pointer?
    Without the old pointer you can't free the memory later.

    Code:
    void alloc_test(NODE_DATA *ND, int c) {
    
        int m = 10;
        int i, j, k;
        int *temp_int;
        double *temp_double;
        
        if (ND == NULL) return; // we don't work with NULL pointer
    
        for (i = 0; i < c; i++) {
            if ((ND[i].ic = malloc(sizeof(int))) == NULL) {
                fprintf(stderr, "No memory left for ND[%d].ic\n", i);
                return;
            }
            if ((ND[i].wc = malloc(sizeof(double))) == NULL) {
                fprintf(stderr, "No memory left for ND[%d].wc\n", i);
                return;
            }
            k = 0;
            for (j = 0; j < m; j++) {
                k++;
                if ((temp_int = realloc(ND[i].ic, k*sizeof(int))) == NULL) {
                    fprintf(stderr, "No memory left for ND[%d].ic in size of %d !\n", i, k);
                    return;
                }
                else {
                    ND[i].ic = temp_int;
                }
                if ((temp_double = realloc(ND[i].wc, k*sizeof(double))) == NULL) {
                    fprintf(stderr, "No memory left for ND[%d].wc in size of %d !\n", i, k);
                    return;
                }
                else {
                    ND[i].wc = temp_double;
                }
            }
        }
    }
    Now, the function has return points in case of fails.
    You should thing of another return value of the function so that the caller become a feedback.
    Other have classes, we are class

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 01-29-2014, 05:17 PM
  2. problem initializing a double array for large array
    By gkkmath in forum C Programming
    Replies: 4
    Last Post: 08-25-2010, 08:26 PM
  3. Replies: 17
    Last Post: 11-22-2008, 03:40 AM
  4. Realloc Double Free
    By ma.mazmaz in forum C Programming
    Replies: 23
    Last Post: 08-05-2008, 02:44 AM
  5. Problem passing double array as a function parameter
    By pppbigppp in forum C++ Programming
    Replies: 7
    Last Post: 06-06-2006, 03:08 AM