【问题标题】:Reallocating memory causes invalid next size [duplicate]重新分配内存会导致下一个大小无效[重复]
【发布时间】: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, &timesStructHasBeenReallocated, currentStructIndexValue, dataRow) == 0)
{
   //Structures have been reallocated so reset the index
   currentStructIndexValue = 0;
}

我已经通过 GDB 中的代码,发现 currentSizenewSize 变量是正确的,即当前大小为 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 是否相同

标签: c structure realloc


【解决方案1】:
        callLogSearchData = (callLogSearchDataStruct*) realloc(callLogSearchData, newSize * sizeof (callLogSearchDataStruct));
        callLogSearch = (callLogSearchResultStruct*) realloc(callLogSearch, newSize * sizeof (callLogSearchResultStruct));
        switches = (switchIDStructure*) realloc(switches, newSize * sizeof (switchIDStructure));

上述分配的左侧是双指针,您尝试分配单个指针。您还可以使用双指针来访问结构的内容。

【讨论】:

    【解决方案2】:

    在您的reallocateStructures 函数中,您为每个项目传递一个指向指针的指针。当您调用realloc() 时,您应该尊重指向指针的指针以获取原始指针,无论是输入参数还是分配结果时。换句话说,您目前拥有:

       callLogSearchData = (callLogSearchDataStruct*) realloc(callLogSearchData, newSize * sizeof (callLogSearchDataStruct));
    

    你想要:

       *callLogSearchData = (callLogSearchDataStruct*) realloc(*callLogSearchData, newSize * sizeof (callLogSearchDataStruct));
    

    【讨论】:

    • 谢谢,这似乎有点工作。至少没有得到 realloc 错误。然而,它在代码中的其他地方崩溃,但我与我原来的问题无关,因为它似乎以某种方式将部分 SQL 查询存储在结构的一部分中,然后越界访问内存。感谢您的帮助
    猜你喜欢
    • 2014-05-18
    • 2014-01-23
    • 2011-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 2012-10-31
    • 1970-01-01
    相关资源
    最近更新 更多