0

我有一个结构,它被定义为将标头作为二进制数据文件的一部分。我用它来读一读,然后使用它的信息。之后我想用它来做另一次阅读。我是否需要释放它或其他任何东西才能再次使用它?

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

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

4 回答 4

2

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

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

编辑:快速浏览一下,不清楚你为什么在这里调用 malloc() 。

于 2012-04-16T18:03:42.047 回答
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 个结构指针的数组。

然后,您尝试hashTable[11]重复访问并分配给第 12 个元素。这可以解释你的“无效读取”,并且注意,做一些越界的写作。

于 2012-04-16T18:39:10.213 回答
0

重新使用“文件头”本身不会导致错误。如果没有来自程序其余部分的更多详细信息,就不可能确切知道导致错误的原因,但这里有几行值得怀疑:

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

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

tempVehicle并且blockHead被分配在堆栈上,如果非常大可能会导致堆栈溢出。

是如何*offsets分配的?至少可以保证大小fileHead.slicesStored吗?

于 2012-04-16T18:20:08.323 回答
0

快速浏览一下,不清楚你为什么在这里调用 malloc() 。

我猜这是因为 RyanS 试图节省声明;“ptr”在循环中用于几个不同的目的(唯一的共同点是,它们都涉及结构顶点节点)。

这不是一个好习惯。目前尚不清楚 malloc 的 ptr 的用途,因为它被分配给然后被丢弃,但如果您只需要一个在循环内使用的缓冲区,请像使用 localstruct vertexNode一样使用 local struct TVehicle3D,与 ptr 分开。

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

ptr = (*ptr).node; 

只需使用ptr = ptr->node.

于 2012-04-16T18:33:37.097 回答