realloc:invalid next size 错误,谁能指出我在内存分配中犯的错误

Posted

技术标签:

【中文标题】realloc:invalid next size 错误,谁能指出我在内存分配中犯的错误【英文标题】:realloc:invalid next size error, can anyone point out the mistake i did in memory allocation 【发布时间】:2020-04-30 19:52:31 【问题描述】: 我传递给 get_document 函数的

text 是一个普通的字符串数据。

1." "表示分词。

2."."表示句子的分离。

3."\n" 表示段落的分隔。

get_document 是一个函数,它将每个单词、句子、段落分配给单独的内存块,使其易于访问。 这是代码sn-p。

char**** get_document(char* text) 
//get_document
int l=0,k=0,j=0,i=0;
char**** document = (char****)malloc(sizeof(char***));//para
document[l] = (char***)malloc(sizeof(char**));//sen
document[l][k] = (char**)malloc(sizeof(char*));//word
document[l][k][j] = (char*)malloc(sizeof(char));//letter

for(int z = 0; z < strlen(text); z++) 

    if(strcmp(&text[z]," ")==0) 
        document[l][k][j][i] = '\0';
        j++;
        document[l][k] = realloc(document[l][k],(sizeof(char*)) * j+1);
        i=0;
        document[l][k][j] = (char*)malloc(sizeof(char));
    
    else if(strcmp(&text[z],".")==0) 
        k++;
        document[l] = realloc(document[l],(sizeof(char**)) * k+1);
        j=0;
        i=0;
        document[l][k] =(char**)malloc(sizeof(char*));
        document[l][k][j] = (char*)malloc(sizeof(char));
    
    else if(strcmp(&text[z],"\n")==0) 
        l++;
        document = realloc(document,(sizeof(char***)) * l+1);
        k=0;
        j=0;
        i=0;
        document[l] = (char***)malloc(sizeof(char**));
        document[l][k] =(char**)malloc(sizeof(char*));
        document[l][k][j] = (char*)malloc(sizeof(char));

    
    else 
        strcpy(&document[l][k][j][i],&text[z]);
        i++;
        document[l][k][j] = realloc(document[l][k][j],(sizeof(char)) * i+1);

    


return document;

但是当我运行程序时,我得到了错误

realloc:invalid next size

谁能帮我解决这个问题。提前致谢。

【问题讨论】:

忠告:如果您发现自己超出了两个间接级别,认真质疑您是否需要做任何您认为自己正在做的事情。对于这个世界上所有美好的事物,stop casting malloc in C programs。也就是说,您的示例输入和调用它并产生错误的驱动 main 是相关的。将它们包含在您的帖子中以制作minimal reproducible example。 char**** 这是一个巨大的设计问题。 现在我明白为什么大多数人不投了,谢谢@WhozCraig 您可能想了解correctly allocating multi-dimensional arrays 关于:****read about 3 star programmer 【参考方案1】:

你把字符和字符串弄乱了。


您检测元素的条件是错误的:

if(strcmp(&text[z]," ")==0)
else if(strcmp(&text[z],".")==0)
...

除非strlen(text) == 1,否则您永远不会进入您的任何分支机构。 strcmp 比较字符串,而不是单个字符。这意味着它将整个剩余缓冲区与长度为 1 的字符串进行比较,除了最后一个字符外,该字符串永远不会为真。 如果要比较单个字符,请改用if(text[z] == ' ')


在你的最后一个 else 分支中,你完全粉碎了你的堆:

strcpy(&document[l][k][j][i],&text[z]);

您将一个字符串(同样:完整的剩余缓冲区)复制到一个字符中。 document[l][k][j] 的内存是使用 size=1 分配的。这甚至不能容纳长度为 1 的字符串,因为没有空间来终止 '\0' 字节。

将字符串复制到大到足以容纳 1 个字符的内存中,会导致堆损坏,并且在任何对内存分配函数的调用中,这最终会爆炸,正如您在错误消息中看到的那样。

你需要的是:

document[l][k][j][i] = text[z];
document[l][k][j][i+1] = 0;

最后你分配的内存大小是错误的:

document = realloc(document,(sizeof(char***)) * l+1);

您想向数组中添加 1 个额外元素,但您只添加了 1 个字节。改用这个:

document = realloc(document,(sizeof(char***)) * (l+1));

这同样适用于所有其他级别的构造。


此外,您对计数器的命名很差。一个字符的变量名只能用于没有混淆风险的循环等。 如果将它们用于不同级别的数组索引,则应使用 wordcountparacount 等名称。这将使代码更具可读性。

另外我建议你遵循 cmets 中的提示。重新思考您的完整设计。

【讨论】:

正如你所说,我必须重新考虑不同的逻辑。谢谢解释【参考方案2】:

当我运行程序时,我得到了错误

realloc:invalid next size

您的一个realloc 调用似乎失败了,因为分配器的跟踪数据已损坏。当您覆盖对象的边界时,这是最常见的错误之一,尤其是分配的边界。你做的很多:

        strcpy(&document[l][k][j][i],&text[z]);

如果您想在 C 学习中取得任何进展,您必须了解 char 和字符串之间的区别。 C 字符串函数,例如strcmp()strcpy(),仅适用于后者。您可以在空字符串(仅包含一个 nul)或单字符串(包含一个字符 加上一个 nul)上使用它们,但它们对个人@987654326 既不安全也不有用@s。对于单个 chars,您可以改用标准 C 运算符,例如 ===

在上面引用的行的情况下,每个strcpy 调用都会尝试将输入字符串的整个尾部(包括终止符)复制到&amp;document[l][k][j][i] 指向的一个-char-big 空间中. 这将总是写入超过分配空间的末尾,通常很多,从而产生未定义的行为。您似乎想要:

        document[l][k][j][i] = text[z];

(当之无愧的批评选择一个四重指针放在一边)。我看到你留下一个字符串终止符以备后用,这原则上是可以的,但我也看到如果句点 ('.') 紧跟在单词后面而没有任何空格,则你无法终止每个句子的最后一个单词。

同样,您对strcmp() 的多次使用都将输入字符串的整个尾部与几个长度为一的字符串文字之一进行比较。允许进行此类比较,但它们不会产生您想要的结果。看来您想要对字符常量进行简单的相等测试,而不是:

    if (text[z] == ' ')
    // ...
    else if (text[z] == '.')
    // ...
    else if (text[z] == '\n')

当然,即使进行了这些更正,您的方法仍然非常低效。内存 [重新] 分配相对昂贵,并且您正在为每个执行分配或重新分配。单身的。特点。在文档中。 至少向前扫描到每个单词的末尾,以便一次分配一个单词,尽管甚至可以做得更好。

另外,不要忽视malloc()realloc() 可能失败的事实,在这种情况下它们会返回一个空指针。健壮的代码会一丝不苟地检查和处理来自其函数调用的错误结果,包括分配错误。

【讨论】:

以上是关于realloc:invalid next size 错误,谁能指出我在内存分配中犯的错误的主要内容,如果未能解决你的问题,请参考以下文章

realloc 使用详解(分析realloc invalid pointer指针无效等错误)

** Error in `./g2o_viewer': realloc(): invalid pointer:

面临错误“检测到 *** glibc *** free(): invalid next size (fast)”

beforeEach钩子,next('/login') 跳转问题,无线循环导致Maximum call stack size exceeded问题

ecnu 3441 Kmp

可持续化栈