Solved

chunk_free (ar_ptr=0x40688620, p=0x8218da7) at malloc.c:3228

Posted on 2004-10-31
391 Views
Last Modified: 2010-05-18
Hello Experts,
I met a very strange problem. It is a bit complicated:
It is a big project, i am coding part of it. I created a static variable in one class -say model.C, this static variable is another class-say Triangles.C. The class Triangles need to read in a few big files and store those values into arrays. For the arrays sizes, at the beginning i hardcoded them as static int num1 = 15128... there are three of them. At that time, it worked allright, it can read in all files and store them to arrays. Then i removed the hardcoded part, i needed to read the array size from the first line of the files. So i had to use pointers to create array(pointer is always a headache for me, i used to learn some Java) . I allocated space for those arrays when reading files. Problem occured now, I got this error when i check the segmentation fault using gdb
#0  0x405d4e9c in chunk_free (ar_ptr=0x40688620, p=0x8218da7) at malloc.c:3228
#1  0x405d4bf4 in __libc_free (mem=0x82192f0) at malloc.c:3154
#2  0x4047b2b6 in __builtin_delete (ptr=0x82192f0) from /usr/local/lib/libGLU.so.1
But the funny thing is when i commented out any two readings(I have four readings altogether), the other two works fine. My friend told me might because it is a static variable and the static memory is limited for a program. If it is true, how come the hardcoded array size case works fine?

Anyone got any idea what is the problem here?
Regards,
Alison
0
Question by:lzha022
    11 Comments
     
    LVL 3

    Expert Comment

    by:Indrawati
    Most probably there's ssomething wrong with the way you allocate and deallocate the memory. Either that, or you performed out-of-bounds array indexing omewhere in the code. Could you post some code where you read the file and allocate/deallocate memory?
    0
     
    LVL 22

    Expert Comment

    by:grg99
    You probably overflowed one of the arrays when reading.  Pls show us your code.

    0
     

    Author Comment

    by:lzha022
    some header code:
    public:
     
      static const int elementNumFields = 3;
      //static const int maxSurfaceVertices = 1543; - used this before
      //static const int maxSurfaceTriangles = 1346;
      //static const int nonZeroEtVertexP = 98753;
      int maxSurfaceVertices,
          maxSurfaceTriangles;
    private:
     CompCol_Mat_double etVertexP;
       VECTOR_double *etVertexPos;
       VECTOR_double etVertexXi[elementNumFields];
        //int etIndices[maxSurfaceTriangles][3];  -used this before
       int **etIndices;
       //int etVertexElementNum[maxSurfaceVertices]; - used this before
       int *etVertexElementNum;
       int etVertexSurfaceStartEnd[totalSurfaces][2],
          etSurfaceStartEnd[totalSurfaces][2];

    some C code:
     Constructor:
        numFields = nFields;
        etVertexPos = new VECTOR_double[numFields];
        dataAlreadyReadIn = false;
        maxSurfaceVertices = 0;
        maxSurfaceTriangles = 0;
        //test
        char *path = cimSprintf("/home/lzhang/CIM_RVLV/resources");
        readDataFiles(path);
      Function readDataFiles:
        readSurfaceStartEnd(resourceDir, 0);
        readSurfaceStartEnd(resourceDir, 1); - this two function will read in values for maxSurfaceVertices  and maxSurfaceTriangles
        allocateSpace();
        readEtVertexP(resourceDir);
        read2DDoubleArray(resourceDir, 0);
        read2DDoubleArray(resourceDir, 1);
        readEtVertexElementNum(resourceDir);
        readEtIndices(resourceDir);
        dataAlreadyReadIn = true;
      Function allocateSpace
        for (i=0; i<elementNumFields; i++)
            etVertexXi[i] = VECTOR_double(maxSurfaceVertices);
        for (i=0; i<numFields; i++)
            etVertexPos[i] = VECTOR_double(maxSurfaceVertices);
        etIndices = new2DMatrixInt(maxSurfaceTriangles, 3);
        etVertexElementNum = new int[maxSurfaceVertices];
      Function new2DMatrixInt
         int **new2DMatrixInt(int row, int col)
       {
          int **mat = (int **)NULL;
          ALLOCATE(mat, int *, row);
          for (int i=0; i<row; i++)
              ALLOCATE(mat[i], int, col);
          return mat;
       } // int **newTw
       
    0
     

    Author Comment

    by:lzha022
    destructor:
     if(etVertexPos != (VECTOR_double *)NULL)
      {
        delete [] etVertexPos;
        etVertexPos = (VECTOR_double *)NULL;
      }
      destroy2DMatrixInt(etIndices, maxSurfaceTriangles);
      delete []etVertexElementNum;
    void destroy2DMatrixInt(int **mat, int row)
    {
      if (mat != (int **)NULL)
      {
        for (int i=0; i<row; i++)
        {
          if (mat[i] != (int *)NULL)
          {
            DEALLOCATE(mat[i]);
            mat[i] = (int *)NULL;
          }
        }
        DEALLOCATE(mat);
      }
    }
    Please note that the function  readEtVertexP reads in a really big file. If i comment out this function, the other read functions work fine. Or if i comment out all other read functions, this one works fine. Tell me if you need more function code.
    Cheers
    Alison
    0
     
    LVL 22

    Expert Comment

    by:grg99
     Function new2DMatrixInt
         int **new2DMatrixInt(int row, int col)
       {
          int **mat = (int **)NULL;
          ALLOCATE(mat, int *, row);
          for (int i=0; i<row; i++)
              ALLOCATE(mat[i], int, col);
          return mat;
       } // int **newTw
       
    ---------------------------------

    Ok, if we assume ALLOCATE() is something like:

    #define ALLOCATE( Dest, Type, Elems )  Dest := (Type *) malloc( sizeof( Type ) * Elems )

    Then the first call allocates enough space for an array of "row"  pointers to int.

    The second call fills that array with "row" new allocations, each big enough for a "col" of ints.

    Now unless you're REALLY careful in casting or using this pointer "mat", you cound be bashing almost anything.
    This is because the returned type is not too useful being an int **.  

    You have to look over every access of "mat" to make sure youre not getting a pointer wedged sideways.
    For example, if you cast it to an array of pointers to pointers to ints, the indexing arithmetic will not be whatr you expect.


    0
     

    Author Comment

    by:lzha022
    Well, i am scared of pointers. From your reply, looks like if i do not use functions to allocate space, but just put those in my allocateSpace function, it will solve the probem.
     for (i=0; i<elementNumFields; i++)
            etVertexXi[i] = VECTOR_double(maxSurfaceVertices);
        for (i=0; i<numFields; i++)
            etVertexPos[i] = VECTOR_double(maxSurfaceVertices);
        //etIndices = new2DMatrixInt(maxSurfaceTriangles, 3);
        ALLOCATE(etIndices, int *, maxSurfaceTriangles);
          for (int i=0; i<maxSurfaceTriangles; i++)
              ALLOCATE(etIndices[i], int, 3);
        etVertexElementNum = new int[maxSurfaceVertices];
    And delete it in destructor.
    I tried this, same problem. What other things can i do?
    0
     
    LVL 39

    Expert Comment

    by:itsmeandnobodyelse
    Could you post the definition of ALLOCATE and DEALLOCATE? Some Compiler's (and me) don't like mixing malloc with operator new.

    >>> etVertexXi[i] = VECTOR_double(maxSurfaceVertices);

    That looks wrong. What is the definition of class VECTOR_double?

    Regards, Alex

       
    0
     

    Author Comment

    by:lzha022
    I found the problem. I did overflow one of the arrays when reading as grg99 said.
     char *filename = (char *)NULL;
      double x;
      int index = 0;
     Function read EtVertexElementNum (char *path)
      filename = cimSprintf("%s/etVertexElementNum.dat",path);
      ifstream ifile(filename, ios::in);
       if (!ifile)
        //show some error message
      else
      {
        index = 0;
        while(ifile)
        {
          ifile >> x;
          etVertexElementNum[index]=(int)x-1;  
          index++;
        }
      }
      ifile.close();
      DEALLOCATE(filename);
    This function always read one more number- i have deleted all spaces at the end of the file:etVertexElementNum.dat. This number is same as the last number in the file. I do not know what to do to solve this problem.
    Regards
    Alison
    0
     
    LVL 22

    Accepted Solution

    by:
    Whenever you're filling an array, it's always a good idea to have:

    if( index <= MaxAllocatedArrayElements ) { do the assignment;  index++; }
    else { Bomb( "VERY BAD ERROR: tried to store into element %d, maximum size is %d", index, MaxAllocatedArrayElements ); }

    I know, it takes an extra nanosecond, but it sure beats having your program bomb whenever somebody types in one line or space too many.

    0
     

    Author Comment

    by:lzha022
    That is a good idea. I focused on how to use ifstream to control it rather than the index. Thanks a lot. By the way, is this error(chunk_free(........) at malloc.c:3228) always related to array overflows?
    Regards,
    Alison
    0
     
    LVL 22

    Expert Comment

    by:grg99
    >By the way, is this error(chunk_free(........) at malloc.c:3228) always related to array overflows?

    It's related to stuff getting bashed past the end of the allocated block, which often happens when you index too far,
    or copy a string that is too long without using the boundschecking strncpy and similar string routines, or when you typecast
    the malloced pointer into a too-big type, or when you use an old or unset pointer and bach something.  Lots of ways to die.

    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
    Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
    The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
    The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

    913 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    18 Experts available now in Live!

    Get 1:1 Help Now