Link to home
Start Free TrialLog in
Avatar of lzha022
lzha022

asked on

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
Avatar of Indrawati
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?
You probably overflowed one of the arrays when reading.  Pls show us your code.

Avatar of lzha022

ASKER

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
   
Avatar of lzha022

ASKER

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
 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.


Avatar of lzha022

ASKER

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?
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

   
Avatar of lzha022

ASKER

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
ASKER CERTIFIED SOLUTION
Avatar of grg99
grg99

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of lzha022

ASKER

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
>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.