我可以重复使用结构进行多次文件读取而不会出现内存错误吗?

时间:2012-04-16 17:53:36

标签: c memory-management struct

我有一个结构被定义为将标题保存为二进制数据文件的一部分。我用它做一次读取然后使用它的信息。之后我想用它来做另一次阅读。在我再次使用之前,我是否需要释放它?

我遇到了一些内存错误,我认为这可能是问题所在。 我包括代码,但它很粗糙,是我尝试调试此问题的当前结果。

void readSlices (struct header fileHead, unsigned long *offsets, FILE *fp, struct car **hashTable, int *tableSize){
    struct TVehicle3D tempVehicle;
    struct BlockHeaderData blockHead;
    struct vertexNode *ptr;
    int sliceNum = 1;
    int i;

    while (sliceNum <= fileHead.slicesStored) {
        fseek (fp, offsets[sliceNum], SEEK_SET);
        fread(&(blockHead),sizeof(blockHead), 1, fp);
        printf ("Type: %d  Size: %d\n", blockHead.objectType,blockHead.size );
        while (blockHead.objectType != 88) {
            if (blockHead.objectType == 86) {
                printf ("Reading slice\n");
                fread(&(tempVehicle),75, 1, fp);

                if (*tableSize < tempVehicle.id) {
                    (*tableSize)++;
                    printf ("increasing tablesize (realloc)\n");
                    *hashTable = realloc(*hashTable, (*tableSize) * sizeof (struct car*));
                };
                if ((*hashTable)[tempVehicle.id].set == 0) {
                    (*hashTable)[tempVehicle.id].set = 1;
                };
                (*hashTable)[tempVehicle.id].sliceOut = sliceNum;
                //printf ("size of table at slice #%d = %d\n",tempVehicle.id, *tableSize);
                tempVehicle.centroid.x = ((tempVehicle.points[0].x)+(tempVehicle.points[1].x)+(tempVehicle.points[2].x)+(tempVehicle.points[3].x))/4;
                tempVehicle.centroid.y = ((tempVehicle.points[0].y)+(tempVehicle.points[1].y)+(tempVehicle.points[2].y)+(tempVehicle.points[3].y))/4;
                tempVehicle.centroid.z = ((tempVehicle.points[0].z)+(tempVehicle.points[1].z)+(tempVehicle.points[2].z)+(tempVehicle.points[3].z))/4;
                ptr = (*hashTable)[tempVehicle.id].node;
                printf ("Set ptr\n");
                for (i = 0; i < sliceNum - (*hashTable)[tempVehicle.id].sliceIn; i++) {
                printf ("Setting loop\n");
                    ptr = (*ptr).node;
                };
                printf ("Setting ptr xyz\n");
                ptr = malloc (sizeof (struct vertexNode));
                ptr->x = tempVehicle.centroid.x;
                (ptr)->y = tempVehicle.centroid.y;
                (ptr)->z = tempVehicle.centroid.z;
                if (tempVehicle.id==1) printf ("centroid x: %d y: %d z: %d\n", tempVehicle.centroid.x, tempVehicle.centroid.y, tempVehicle.centroid.z);
            }
            else fseek (fp, ftell(fp) + blockHead.size, SEEK_SET);
            fread(&(blockHead),sizeof(blockHead), 1, fp);
            //printf ("Type: %d  Size: %d\n", blockHead.objectType,blockHead.size );
        };
        sliceNum++;
    };
}

4 个答案:

答案 0 :(得分:2)

您可以随意重复使用缓冲区。

查看您的代码,我看到您ptr = malloc(...);,但您粘贴的代码中永远不会free(ptr);。这将导致内存泄漏。你的malloc()在你的循环中,导致潜在的非常严重的泄漏。

编辑:快看,目前还不清楚为什么你在这里调用malloc()。

答案 1 :(得分:2)

看这里:

  if (*tableSize < tempVehicle.id) {
                (*tableSize)++;
                printf ("increasing tablesize (realloc)\n");
                *hashTable = realloc(*hashTable, (*tableSize) * sizeof (struct car*));
            };
            if ((*hashTable)[tempVehicle.id].set == 0) {
                (*hashTable)[tempVehicle.id].set = 1;
            };

我们假设tablesize是10,tempVehicle.id是11,所以你将tablesize增加到11并且realloc hashTable是一个包含11个struct指针的数组。

然后你尝试重复访问并分配给hashTable[11] - 第12个元素。这可以解释你的&#34;无效的阅读&#34;和nb。,做一些越界写作。

答案 2 :(得分:0)

重新使用'filehead'本身不会导致错误。如果没有来自程序其余部分的更多细节,就不可能确切地知道导致错误的原因,但这里有几行是可疑的:

fread(&(tempVehicle),75, 1, fp);

sizeof(tempVehicle)至少是75个字节吗?

tempVehicleblockHead在堆栈上分配,如果非常大可能导致堆栈溢出。

如何分配*offsets?是否保证大小至少为fileHead.slicesStored

答案 3 :(得分:0)

  

快看,目前还不清楚为什么你要调用malloc()   这里。

我猜是因为RyanS试图保存声明; “ptr”在循环中用于几个不同的目的(唯一的共性是,它们都涉及struct vertexNode)。

这不是一个好习惯。目前还不清楚malloc的ptr是什么用的,因为它被分配然后扔掉了,但是如果你只需要一个缓冲区在循环中使用,那就像使用本地{{1}一样使用本地struct vertexNode分离ptr。

注意mah关于泄漏的观点。 这是一个非常严重的问题。另外:这是一个非常规的陈述:

struct TVehicle3D

只需使用ptr = (*ptr).node;