【发布时间】:2013-09-16 16:33:00
【问题描述】:
我正在做一个 C 项目,我对 C 很陌生,所以这可能是一个非常简单的答案,但我不知道如何解决这个问题。
我所拥有的是一个结构,它以以下方式在头文件中定义。
typedef struct CallLogSearchDataStruct
{
char * date;
char * time;
char * bParty;
char * aParty;
float duration;
char * cleardownCause;
struct CallLogSearchOutboundStruct * outboundLegs;
} callLogSearchDataStruct;
然后使用以下代码 sn-p 对其进行引用和分配。
callLogSearchDataStruct * callLogSearchData = NULL;
callLogSearchData = (callLogSearchDataStruct*)calloc(INITIAL_CALL_STRUCT_SIZE,sizeof(callLogSearchDataStruct));
INITIAL_CALL_STRUCT_SIZE 设置为 100。
我有一些代码在 while 循环中循环,该循环递增一个名为 currentStructIndexValue 的变量。每次增加这个值时,我都会调用一个名为reallocateStructures 的函数。这包含各种参数,例如我要重新分配的结构数组。
即应该发生什么,callLogSearchDataStructure 被调用为 100 的大小。当 currentStructIndexValue 值变为 101 并调用 reallocateStructures 函数时,该结构应该调整大小以包含另一个 100,即现在包含 200 个。
下面是我遇到问题的 reallocateStructures 函数的代码。
int reallocateStructures(callLogSearchResultStruct **callLogSearch, callLogSearchDataStruct ** callLogSearchData,
switchIDStructure ** switches, int *timesStructHasBeenReallocated, int currentStructIndexValue,
int dataRow)
{
int INITIAL_CALL_STRUCT_SIZE = 100;
int currentSize = 0;
int newSize = 0;
int initFromIndex = 0;
if (currentStructIndexValue == INITIAL_CALL_STRUCT_SIZE) {
printf("REALLOCATING STRUCTURES");
currentSize = currentStructIndexValue * *timesStructHasBeenReallocated;
newSize = currentSize + INITIAL_CALL_STRUCT_SIZE;
*timesStructHasBeenReallocated = *timesStructHasBeenReallocated + 1;
callLogSearchData = (callLogSearchDataStruct*) realloc(callLogSearchData, newSize * sizeof (callLogSearchDataStruct));
callLogSearch = (callLogSearchResultStruct*) realloc(callLogSearch, newSize * sizeof (callLogSearchResultStruct));
switches = (switchIDStructure*) realloc(switches, newSize * sizeof (switchIDStructure));
for (initFromIndex = currentSize; initFromIndex < newSize; initFromIndex++) {
callLogSearchData[initFromIndex]->aParty = NULL;
callLogSearchData[initFromIndex]->bParty = NULL;
callLogSearchData[initFromIndex]->cleardownCause = NULL;
callLogSearchData[initFromIndex]->date = NULL;
callLogSearchData[initFromIndex]->duration = 0;
callLogSearchData[initFromIndex]->outboundLegs = NULL;
callLogSearchData[initFromIndex]->time = NULL;
callLogSearch[initFromIndex]->date = NULL;
callLogSearch[initFromIndex]->dRowIndex = dataRow;
switches[initFromIndex]->switchID = NULL;
}
return 0;
}
return 1;
}
下面是我如何调用上述方法
if (reallocateStructures(&callLogSearch, &callLogSearchData, &switches, ×StructHasBeenReallocated, currentStructIndexValue, dataRow) == 0)
{
//Structures have been reallocated so reset the index
currentStructIndexValue = 0;
}
我已经通过 GDB 中的代码,发现 currentSize,newSize 变量是正确的,即当前大小为 100,新大小将为 200,但是当它为 callLogSearchData 执行第一次重新分配时应用程序崩溃并显示以下 GDB 消息
*** glibc detected *** realloc(): invalid size: 0xbfffed18 ***
*** glibc detected *** realloc(): invalid pointer: 0xbfffed1c ***
*** glibc detected *** realloc(): invalid pointer: 0xbfffed14 ***
感谢您提供的任何帮助。
【问题讨论】:
-
您的代码在某个地方破坏了堆,否则
realloc不会失败。我建议您使用valgrind。 -
我查看了 Valgrind 并浏览了它的教程,但日志中并非所有内容都有意义。它有助于解决我遇到的其他问题,但不幸的是不是这个
-
作为第一个响应,提到的错误看起来更像是一个十六进制地址而不是数字 200...就像在这个答案中stackoverflow.com/questions/2939091/realloc-invalid-next-size 我怀疑你可能会以某种方式过度运行 malloc 数据结构...但是,您的问题很好,并且有很多信息。我会慢慢解决的。
-
感谢 unwind,我在某个地方读到了你应该转换的内容,这是否仅适用于 malloc 或者对于你不应该转换的 calloc 和 realloc 是否相同