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

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
lzha022Asked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
grg99Connect With a Mentor Commented:
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
 
IndrawatiCommented:
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
 
grg99Commented:
You probably overflowed one of the arrays when reading.  Pls show us your code.

0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
lzha022Author Commented:
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
 
lzha022Author Commented:
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
 
grg99Commented:
 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
 
lzha022Author Commented:
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
 
itsmeandnobodyelseCommented:
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
 
lzha022Author Commented:
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
 
lzha022Author Commented:
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
 
grg99Commented:
>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
All Courses

From novice to tech pro — start learning today.