C 增加结构大小,然后将其重置为原始大小,然后再次增加大小
我是C语言的新手,但我目前正在编写一个C程序,在结构和内存分配方面我遇到了一个问题 我的代码中有一个永久的while循环,当满足某个条件时,该循环将中断。在这个while循环中,它检查数据库,并有一个while循环来循环MySQL行 当程序首次加载时,它会创建3个结构,其中一个结构还包含一个链表,并初始化为100大小C 增加结构大小,然后将其重置为原始大小,然后再次增加大小,c,structure,realloc,C,Structure,Realloc,我是C语言的新手,但我目前正在编写一个C程序,在结构和内存分配方面我遇到了一个问题 我的代码中有一个永久的while循环,当满足某个条件时,该循环将中断。在这个while循环中,它检查数据库,并有一个while循环来循环MySQL行 当程序首次加载时,它会创建3个结构,其中一个结构还包含一个链表,并初始化为100大小 //Check if function has looped round already and if so reset all structures if (da
//Check if function has looped round already and if so reset all structures
if (dataRow > -1)
{
numberOfTimesEverythingHasReset++;
callLogSearchData = NULL;
callLogSearch = NULL;
switches = NULL;
callLogSearchData = realloc(callLogSearchData, INITIAL_CALL_STRUCT_SIZE*sizeof(callLogSearchDataStruct));
callLogSearch = realloc(callLogSearch, INITIAL_CALL_STRUCT_SIZE*sizeof(callLogSearchResultStruct));
switches = realloc(switches, INITIAL_CALL_STRUCT_SIZE*sizeof(switchIDStructure));
//initialiseNewStructure(&callLogSearch, &callLogSearchData, &switches);
//callLogSearchData = (callLogSearchDataStruct*)realloc(callLogSearchData, INITIAL_CALL_STRUCT_SIZE*sizeof(callLogSearchDataStruct));
//callLogSearch = (callLogSearchResultStruct*)realloc(callLogSearch, INITIAL_CALL_STRUCT_SIZE*sizeof(callLogSearchResultStruct));
//switches = (switchIDStructure*)realloc(switches, INITIAL_CALL_STRUCT_SIZE*sizeof(switchIDStructure));
//Initialise all elements within structures
for (initFromIndex = INITIAL_CALL_STRUCT_SIZE; initFromIndex < INITIAL_CALL_STRUCT_SIZE; 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;
}
timesStructHasBeenReallocated = 1;
currentSize = 0;
}
currentStructIndexValue = 0;
当我的程序在MySQL行中循环时,它会检查是否添加了100条记录,如果添加了,则执行realloc将大小再增加100行。当我遍历所有MySQL行时,它会返回main while循环(永无止境的循环)和NULL的结构,然后将它们再次初始化为100行并重新开始
我遇到的问题是,一旦它通过所有mysql行执行第一个完整的循环,并返回到主永无止境的循环,并且结构被重新初始化为100大小,在第17行我的程序segfaults。当我检查GDB中的所有内容时,索引17处的结构出现,表示结构中的某些元素超出了范围
下面是我遇到问题的结构的定义
typedef struct CallLogSearchDataStruct
{
char * date;
char * time;
char * bParty;
char * aParty;
float duration;
char * cleardownCause;
struct CallLogSearchOutboundStruct * outboundLegs;
} callLogSearchDataStruct;
下面是程序第一次运行时结构最初是如何设置的
callLogSearchData = calloc(INITIAL_CALL_STRUCT_SIZE,sizeof(callLogSearchDataStruct));
callLogSearch = calloc(INITIAL_CALL_STRUCT_SIZE,sizeof(callLogSearchResultStruct));
switches = calloc(INITIAL_CALL_STRUCT_SIZE, sizeof(switchIDStructure));
INITIAL\u CALL\u STRUCT\u SIZE
等于100
下面是如何调用reallocateStructures函数的代码。这将通过在原始大小的基础上再添加100个大小来重新分配结构
if (reallocateStructures(&callLogSearch, &callLogSearchData, &switches, ×StructHasBeenReallocated, currentStructIndexValue, dataRow) == 0)
{
//Structures have been reallocated so reset the index
currentStructIndexValue = 0;
}
下面是重新分配结构的实际代码
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;
callLogSearchResultStruct * callLogSearchTemp;
callLogSearchDataStruct * callLogSearchDataTemp;
switchIDStructure * switchesTemp;
printf("Current Struct Index Value: %i\n", currentStructIndexValue);
if (currentStructIndexValue >= INITIAL_CALL_STRUCT_SIZE) {
printf("REALLOCATING STRUCTURES");
currentSize = currentStructIndexValue * *timesStructHasBeenReallocated;
newSize = currentSize + INITIAL_CALL_STRUCT_SIZE;
*timesStructHasBeenReallocated = *timesStructHasBeenReallocated + 1;
callLogSearchTemp= (callLogSearchResultStruct*)realloc(*callLogSearch, (newSize * sizeof(callLogSearchResultStruct)));
callLogSearchDataTemp = (callLogSearchDataStruct*)realloc(*callLogSearchData, (newSize * sizeof(callLogSearchDataStruct)));
switchesTemp = (switchIDStructure*)realloc(*switches, (newSize * sizeof(switchIDStructure)));
/**callLogSearchData = realloc(*callLogSearchData, newSize * sizeof (callLogSearchDataStruct));
*callLogSearch = realloc(*callLogSearch, newSize * sizeof (callLogSearchResultStruct));
*switches = realloc(*switches, newSize * sizeof (switchIDStructure));
*/
for (initFromIndex = currentSize; initFromIndex < newSize; initFromIndex++) {
callLogSearchDataTemp[initFromIndex].aParty = NULL;
callLogSearchDataTemp[initFromIndex].bParty = NULL;
callLogSearchDataTemp[initFromIndex].cleardownCause = NULL;
callLogSearchDataTemp[initFromIndex].date = NULL;
callLogSearchDataTemp[initFromIndex].duration = 0;
callLogSearchDataTemp[initFromIndex].outboundLegs = NULL;
callLogSearchDataTemp[initFromIndex].time = NULL;
callLogSearchTemp[initFromIndex].date = NULL;
callLogSearchTemp[initFromIndex].dRowIndex = dataRow;
switchesTemp[initFromIndex].switchID = NULL;
if (initFromIndex == newSize - 1)
{
printf("debugging here\n");
}
}
*callLogSearch = callLogSearchTemp;
*callLogSearchData = callLogSearchDataTemp;
*switches = switchesTemp;
return 0;
}
else
{
return 1;
}
}
当我检查GDB中的rowReport时,它似乎内部有垃圾,在第7个索引(bPartyColIndex
位于索引9)处,我开始看到越界错误
rowReport在每次为每个mysql行分配循环时都被分配,如下代码所示
sqlLen = asprintf(&sql, "SELECT Tmp.SwitchID, Tmp.CorrelationID, SeizeUTC as Date, "
"SeizeUTC as Time, Direction, ACMToAns/100 as ACMToAns, Duration/100 as Duration, "
"CleardownCause, AParty, Tmp.BParty FROM TMP_Log AS Tmp ORDER BY SeizeUTC, "
"Tmp.SwitchID, Tmp.CorrelationID, Direction, SeizeCSec LIMIT %i, %i",
index, count);
SL_DebugAll(DBG_INFO, sql);
if ((mysql_real_query(HandleDB, sql, sqlLen))) return 1;
resultReport = mysql_store_result(HandleDB);
if (mysql_num_rows(resultReport) == 0 || index > atoi(limit))
{
SL_DebugAll(DBG_INFO, "Data retrieval for call log complete");
break;
}
else
{
numRows = mysql_num_rows(resultReport);
swID = -1;
corrID = -1;
dataRow = -1;
if (numRows > 0)
{
maxTargets = 1;
}
audioRow = mysql_fetch_row(audioResult);
sspSwitchID = atoi(audioRow[switchIDColIndex]);
sspCorrID = atoi(audioRow[correlationIDColIndex]);
inbound_counter = 0;
while (rowReport = mysql_fetch_row(resultReport))
在你的最后一段代码中
if (dataRow > -1)
{
numberOfTimesEverythingHasReset++;
callLogSearchData = NULL;
callLogSearch = NULL;
switches = NULL;
callLogSearchData = realloc(callLogSearchData,
INITIAL_CALL_STRUCT_SIZE*sizeof(callLogSearchDataStruct));
callLogSearch = realloc(callLogSearch,
INITIAL_CALL_STRUCT_SIZE*sizeof(callLogSearchResultStruct));
switches = realloc(switches,
INITIAL_CALL_STRUCT_SIZE*sizeof(switchIDStructure));
//Initialise all elements within structures
for (initFromIndex = INITIAL_CALL_STRUCT_SIZE;
initFromIndex < INITIAL_CALL_STRUCT_SIZE;
initFromIndex++)
{
....
if(数据行>-1)
{
numberOfTimesEverythingHasReset++;
callLogSearchData=NULL;
callLogSearch=NULL;
开关=空;
callLogSearchData=realloc(callLogSearchData,
初始调用结构大小*sizeof(callLogSearchDataStruct));
callLogSearch=realloc(callLogSearch,
初始调用结构大小*sizeof(callLogSearchResultStruct));
开关=realloc(开关,
初始调用结构大小*sizeof(switchIDStructure));
//初始化结构中的所有元素
for(initFromIndex=初始调用结构大小;
initFromIndex
您正在将callLogSearchData
设置为NULL
,因此重新分配不相关
您正在分配
INITIAL\u CALL\u STRUCT\u SIZE
元素数,但for循环计数器从INITIAL\u CALL\u STRUCT\u SIZE
开始,因此for循环无法有效执行。我已经设法找出了问题所在,不幸的是,这是一个非常基本的错误
由于代码崩溃的地方,我认为这一定与我重新初始化结构的方式有关,可能是因为我使用指针的方式
然而,事实并非如此,相反,在代码的其他地方,我使用名为fileRow
的索引向其中一个结构添加了一些数据。每次向结构添加一个值时,我都会增加fileRow,但在重新定位结构时,我忘了将其重置回0,因此,当我重新定位结构时,将其重置为o如果大小为100,我将插入文件行所在的结构,该结构设置为1300,因此每次循环时,我都会破坏内存,直到它出现故障
感谢您的帮助和建议。对不起,您在问什么可能不是您当前的问题,但请注意,您没有处理可能的realloc故障。与其为重新分配结构的次数设置一个变量,不如设置一个具有当前索引和大小的变量。“当前索引”不断向上,是分配的“数组”中最后使用的条目的索引。大小是分配的条目数,以
初始调用\u结构\u大小开始,并且它也不断向上增长。如果您增加“当前索引”并且它等于“当前大小”,则是重新分配和增加的时候了"当前大小。此外,如果currentStructIndexValue
是数组中最后一个条目的索引,则将其重置为零将导致覆盖旧条目。@JoachimPileborg,谢谢,我不知道新大小的计算是个问题,尽管您的建议可能比我使用的方法更简洁。有一个单独的I我正在使用的ndex称为dataRow,用于向结构添加元素。currentStructIndexValue
将从0变为100,在100时,realloc完成,如果返回成功的realloc,变量将重置为0并重新启动。是的,现在看起来很明显。因此,要将结构重置为空,但又只有100项,w这将是最好的方法,而不是空结构,只执行calloc,或者realloc很好,我只是不需要空结构first@Boardy,我想从0
到INITIAL\u CALL\u STRUCT\u SIZE
开始for loop
。是的,我理解这一点,但你也说过我正在将callLogSearchData设置为NULL,因此重新分配是notrelevant@Boardy,如果要重新分配,则无需执行任何其他操作,只需将值适当重置为0或NULL
,并将跟踪长度的变量设置为新值。
if (dataRow > -1)
{
numberOfTimesEverythingHasReset++;
callLogSearchData = NULL;
callLogSearch = NULL;
switches = NULL;
callLogSearchData = realloc(callLogSearchData,
INITIAL_CALL_STRUCT_SIZE*sizeof(callLogSearchDataStruct));
callLogSearch = realloc(callLogSearch,
INITIAL_CALL_STRUCT_SIZE*sizeof(callLogSearchResultStruct));
switches = realloc(switches,
INITIAL_CALL_STRUCT_SIZE*sizeof(switchIDStructure));
//Initialise all elements within structures
for (initFromIndex = INITIAL_CALL_STRUCT_SIZE;
initFromIndex < INITIAL_CALL_STRUCT_SIZE;
initFromIndex++)
{
....