Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 增加结构大小,然后将其重置为原始大小,然后再次增加大小_C_Structure_Realloc - Fatal编程技术网

C 增加结构大小,然后将其重置为原始大小,然后再次增加大小

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

我是C语言的新手,但我目前正在编写一个C程序,在结构和内存分配方面我遇到了一个问题

我的代码中有一个永久的while循环,当满足某个条件时,该循环将中断。在这个while循环中,它检查数据库,并有一个while循环来循环MySQL行

当程序首次加载时,它会创建3个结构,其中一个结构还包含一个链表,并初始化为100大小

//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, &timesStructHasBeenReallocated, 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++)
        {
           ....