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
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
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.
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[elementNumField s];
//int etIndices[maxSurfaceTriang les][3]; -used this before
int **etIndices;
//int etVertexElementNum[maxSurf aceVertice s]; - used this before
int *etVertexElementNum;
int etVertexSurfaceStartEnd[to talSurface s][2],
etSurfaceStartEnd[totalSur faces][2];
some C code:
Constructor:
numFields = nFields;
etVertexPos = new VECTOR_double[numFields];
dataAlreadyReadIn = false;
maxSurfaceVertices = 0;
maxSurfaceTriangles = 0;
//test
char *path = cimSprintf("/home/lzhang/C IM_RVLV/re sources");
readDataFiles(path);
Function readDataFiles:
readSurfaceStartEnd(resour ceDir, 0);
readSurfaceStartEnd(resour ceDir, 1); - this two function will read in values for maxSurfaceVertices and maxSurfaceTriangles
allocateSpace();
readEtVertexP(resourceDir) ;
read2DDoubleArray(resource Dir, 0);
read2DDoubleArray(resource Dir, 1);
readEtVertexElementNum(res ourceDir);
readEtIndices(resourceDir) ;
dataAlreadyReadIn = true;
Function allocateSpace
for (i=0; i<elementNumFields; i++)
etVertexXi[i] = VECTOR_double(maxSurfaceVe rtices);
for (i=0; i<numFields; i++)
etVertexPos[i] = VECTOR_double(maxSurfaceVe rtices);
etIndices = new2DMatrixInt(maxSurfaceT riangles, 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
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[elementNumField
//int etIndices[maxSurfaceTriang
int **etIndices;
//int etVertexElementNum[maxSurf
int *etVertexElementNum;
int etVertexSurfaceStartEnd[to
etSurfaceStartEnd[totalSur
some C code:
Constructor:
numFields = nFields;
etVertexPos = new VECTOR_double[numFields];
dataAlreadyReadIn = false;
maxSurfaceVertices = 0;
maxSurfaceTriangles = 0;
//test
char *path = cimSprintf("/home/lzhang/C
readDataFiles(path);
Function readDataFiles:
readSurfaceStartEnd(resour
readSurfaceStartEnd(resour
allocateSpace();
readEtVertexP(resourceDir)
read2DDoubleArray(resource
read2DDoubleArray(resource
readEtVertexElementNum(res
readEtIndices(resourceDir)
dataAlreadyReadIn = true;
Function allocateSpace
for (i=0; i<elementNumFields; i++)
etVertexXi[i] = VECTOR_double(maxSurfaceVe
for (i=0; i<numFields; i++)
etVertexPos[i] = VECTOR_double(maxSurfaceVe
etIndices = new2DMatrixInt(maxSurfaceT
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
ASKER
destructor:
if(etVertexPos != (VECTOR_double *)NULL)
{
delete [] etVertexPos;
etVertexPos = (VECTOR_double *)NULL;
}
destroy2DMatrixInt(etIndic es, 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
if(etVertexPos != (VECTOR_double *)NULL)
{
delete [] etVertexPos;
etVertexPos = (VECTOR_double *)NULL;
}
destroy2DMatrixInt(etIndic
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.
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.
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(maxSurfaceVe rtices);
for (i=0; i<numFields; i++)
etVertexPos[i] = VECTOR_double(maxSurfaceVe rtices);
//etIndices = new2DMatrixInt(maxSurfaceT riangles, 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?
for (i=0; i<elementNumFields; i++)
etVertexXi[i] = VECTOR_double(maxSurfaceVe
for (i=0; i<numFields; i++)
etVertexPos[i] = VECTOR_double(maxSurfaceVe
//etIndices = new2DMatrixInt(maxSurfaceT
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(maxSurfaceVe rtices);
That looks wrong. What is the definition of class VECTOR_double?
Regards, Alex
>>> etVertexXi[i] = VECTOR_double(maxSurfaceVe
That looks wrong. What is the definition of class VECTOR_double?
Regards, Alex
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/etVertexEle mentNum.da t",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.da t. This number is same as the last number in the file. I do not know what to do to solve this problem.
Regards
Alison
char *filename = (char *)NULL;
double x;
int index = 0;
Function read EtVertexElementNum (char *path)
filename = cimSprintf("%s/etVertexEle
ifstream ifile(filename, ios::in);
if (!ifile)
//show some error message
else
{
index = 0;
while(ifile)
{
ifile >> x;
etVertexElementNum[index]=
index++;
}
}
ifile.close();
DEALLOCATE(filename);
This function always read one more number- i have deleted all spaces at the end of the file:etVertexElementNum.da
Regards
Alison
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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
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.
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.