【问题标题】:Issues using realloc (old size)使用 realloc 的问题(旧大小)
【发布时间】:2021-10-31 04:17:47
【问题描述】:

我正在尝试在 C 中使用 realloc 函数来动态操作字符串的 char 数组 (char**)。 在 for 循环的第 41 个 cicle 之后,我通常会收到 realloc():invalid old size 错误,我真的不明白为什么。 所以,感谢所有帮助我的人^-^

[编辑] 作为这个社区的“新活跃成员”,我正在努力使帖子更加清晰并遵循您的建议,所以谢谢大家!

typedef struct _WordsOfInterest {  // this is in an header file containing just
    char **saved;                  // the struct and libraries
    int index;
} wordsOfInterest;


int main() {
    char *token1, *token2, *save1 = NULL, file[LEN], *temp, *word, **tokenArr;
    int n=0, ch,ch2, flag=0, size, init=0,position,currEdit,init2=0,tempEdit,size_arr=LEN, 
        oldIndex=0,totalIndex=0,*editArr,counterTok=0;
    wordsOfInterest toPrint;
    char **final;
    toPrint.index = 0;
    toPrint.saved = malloc(sizeof(char*)*LEN);
    editArr = malloc(sizeof(int)*LEN);
    tokenArr = malloc(sizeof(char*)*LEN);
    final = malloc(sizeof(char*)*1);


    // external for loop 
    for(...) {
        tokenArr[counterTok] = token1;
        // internal while loop
        while(...) {
            // some code here surely not involved in the issue
        } else {
            if(init2 == 0) {
                currEdit = config(token1,token2);
                toPrint.saved[toPrint.index] = token2;
                toPrint.index++;
                init2 = 1;
            } else {
                if((abs((int)strlen(token1)-(int)strlen(token2)))<=currEdit) {
                    if((tempEdit = config(token1,token2)) == currEdit) {
                        toPrint.saved[toPrint.index] = token2;
                        toPrint.index++;
                        if(toPrint.index == size_arr-1) {
                            size_arr = size_arr*2;
                            toPrint.saved = realloc(toPrint.saved, size_arr);
                        }
                    } else if((tempEdit = config(token1,token2))<currEdit) {
                        freeArr(toPrint, size_arr);
                        toPrint.saved[toPrint.index] = token2;
                        toPrint.index++;
                        currEdit = tempEdit;
                    }
                }
            }
            flag = 0;
            word = NULL;
            temp = NULL;
            freeArr(toPrint, size_arr);
        }
    }
    editArr[counterTok] = currEdit;
    init2 = 0;
    totalIndex = totalIndex + toPrint.index + 1;
    final = realloc(final, (sizeof(char*)*totalIndex));
    uniteArr(toPrint, final, oldIndex); 
    oldIndex = toPrint.index;
    freeArr(toPrint,size_arr);
    fseek(fp2,0,SEEK_SET);
    counterTok++;
}

【问题讨论】:

  • realloc(toPrint.saved, size_arr) 太小了。发布minimal reproducible example
  • 你在末尾多了一个}
  • 您有一个else,但没有if
  • 什么是toPrint?它的成员有哪些?它是如何初始化的?您是否尝试过找到一些总是复制问题的案例?你试过调试吗?您是否尝试过在调试器中捕获崩溃?
  • 尝试做例如realloc(toPrint.saved, sizeof(*toPrint.saved) * size_arr) 代替。

标签: c memory size realloc


【解决方案1】:

您以未初始化的final 开头。

        char **final;

改成:

        char **final = NULL;

即使您一开始没有分配,它也需要一个有效值(例如NULL),因为如果您不将局部变量初始化为NULL,它就会变成垃圾,realloc() 会认为它是重新分配有效的内存块并将失败为未定义行为。这可能是您的问题,但是由于您在声明和realloc 的第一次使用之间删除了很多代码,所以他无法猜测这里发生了什么。

无论如何,如果你确实初始化了它,我不能说,因为你隐藏了部分代码,没有听取How to create a Minimal, Reproducible Example 的建议。

提供完整但最小的、开箱即用的失败代码有几个原因(主要在此处进行了解释)。这使我们能够测试该代码,而无需提供(并且可能解决全部或部分)必要的代码以使其运行。如果您只发布一个概念,您就无法期望我们提供完整、完整运行且经过测试的代码,这会严重降低 SO 答案的质量。

这意味着你在发布之前还有工作要做,而不是仅仅消除你认为不值得一提的东西。

  • 您需要构建一个示例,用最少的代码显示您看到的实际行为(一个无法运行的完整程序)这意味着消除与问题无关的所有内容。
  • 在发送代码之前,您需要(这一点更为重要)在您的站点上对其进行测试,并查看其行为是否与您在家中看到的一样。有许多示例在消除不相关的代码后,不会显示注释行为。
  • ...然后,不再接触代码,按原样发送。很多时候,我们看到代码在发送之前已经被触及,问题就消失了。

如果我们需要构建一个程序,我们可能会犯许多其他错误,但不是您的错误,这违背了本论坛的目的。

最后,对火焰感到抱歉....但有必要让人们阅读规则。

【讨论】:

    猜你喜欢
    • 2012-07-09
    • 2014-08-26
    • 2015-02-05
    • 2013-05-16
    • 1970-01-01
    • 2013-09-08
    • 2012-02-02
    • 1970-01-01
    相关资源
    最近更新 更多