【问题标题】:Getting (core dumped) when using realloc使用 realloc 时获取(核心转储)
【发布时间】:2015-11-13 20:10:10
【问题描述】:
void replace(char *str) {
    unsigned int len = 0;
    unsigned int no_of_spaces = 0;
    while (*str) {
        if ((char)*str == SPACE)
            no_of_spaces++;
        str++;
        len++;
    }

    unsigned int new_len = len + 2 * no_of_spaces;
    str = (char*) realloc(str, new_len * sizeof(char));
    str[new_len] = '\0';
}

我使用像replace("random string");这样的函数。

这里我试图增加字符串的大小,以便可以用另一个字符串替换空格。为此,我需要计算空格的数量并获取原始字符串的长度。我已经做到了。

为了调整大小,我使用的是realloc,但是当我运行它时,它会给出Aborted (core dumped)?

【问题讨论】:

  • realloc 如果调用失败返回NULL,你应该检查一下.....
  • 显示你如何调用replace以及你将ass参数传递给replace
  • 我在下面的 cmets 中提到过。就像replace("random string")

标签: c memory-management realloc


【解决方案1】:

唯一可以传递给realloc的指针是空指针以及之前由callocmallocrealloc返回的指针!

这很重要,因为您提到您已将函数称为 replace("random string")... "random string" 是空指针,还是由其中一个 *alloc 函数返回?不。也许您打算使用strdup 或其他东西(例如char *foo = strdup("random string"); replace(foo); free(foo);)? strdup 是一个 POSIX 函数(例如,不是像 *alloc 函数那样的 C 标准),但它应该返回由 *alloc 函数返回的内容。


遵循此代码:

unsigned int new_len = len + 2 * no_of_spaces;
str = (char*) realloc(str, new_len * sizeof(char)); /* NOTE there's a potential memory leak
                                                     * when realloc returns NULL here, though
                                                     * that's the least of your problems */

...您必须检查str 以确保realloc 成功,只有这样str 的唯一有效索引在0 和new_len - 1 之间。这要么是空指针取消引用,要么是缓冲区溢出:

str[new_len] = '\0';

也许你的意思是:

size_t new_len = len + 2 * no_of_spaces;
void *temp = realloc(str, new_len + 1); /* <--- NOTE +1 HERE! */
if (temp == NULL) {
    /* XXX: Bomb out due to allocation failure */
}
str = temp;

...现在有效索引在 0 和 new_len + 1 - 1 之间,所以这是有效的:

str[new_len] = '\0';

【讨论】:

【解决方案2】:

你也可以移动指针

while (*str) {
    if ((char)*str == SPACE)
        no_of_spaces++;
    str++;
    len++;
}

当你走到最后时,你会尝试重新分配它。但是您已经远离数组所在的位置。在此处使用临时变量。 正如其他人所说。该字符串希望是使用 malloc 而不是作为数组创建的。

str[new_len] = '\0'; 越界了。

【讨论】:

    【解决方案3】:

    您的原始字符串是使用 malloc 分配的吗?还是重新分配?也许您正在尝试增加静态字符串(字符串文字)的大小:

    char sStatic[256];   // cannot realloc
    
    char *sNonStatic = NULL;   // can / must realloc
    
    replace("random string") // cannot realloc within replace
    

    编辑:阅读您的评论后,您应该复制传入的字符串,增加大小,然后输出一个副本/新字符串。您不能增加常量字符串(字符串文字)的大小。

    【讨论】:

    • 猜得好 - 没想到那个!
    • 答案已修改。你不能增加这种常量字符串
    • 当您尝试将字符串文字传递给采用 char * 的函数时,您的编译器应该给您一个警告 - 您没有启用警告(在这种情况下启用它们!)或者您选择忽略警告(为什么?)。
    • @AnimeshPandey 一点也不。您可以在整个应用程序中轻松使用“已分配”字符串,这些字符串可以重新分配。但在这种情况下,您接受原始用户输入作为字符串常量。好的做法是始终对字符串进行完整性检查并将其复制到动态缓冲区中。 (健全性检查 - 不会太长,没有坏字符等)
    • @AnimeshPandey:好的 - 那么你应该看到警告了吗?
    【解决方案4】:

    此行不正确,因为有效索引范围为 0 .. new_len - 1

    str[new_len] = '\0';
    

    应该是这样的:

    str[new_len - 1] = '\0';
    

    您还有一些其他潜在问题:

    • realloc 可以返回 NULL - 你应该检查这个

    • 1234563设置 str 等于 temp:

    char * temp = realloc(str, new_len);
    if (temp == NULL)
    {
        // handle error here...
    }
    else
    {
        str = temp; // success...
        str[new_len - 1] = '\0';
    }
    

    • 本身并不是一个错误,但是您有很多不必要的强制转换,这些强制转换具有潜在的危险,因为它们可以掩盖错误,否则会产生编译器错误或警告。您可以安全地删除上述代码中的所有强制转换。

    【讨论】:

    • 我改了,但还是出现同样的错误!!
    • 你需要修复所有的错误——这只是其中之一。
    猜你喜欢
    • 2015-11-18
    • 1970-01-01
    • 2019-07-22
    • 2021-07-19
    • 1970-01-01
    • 2017-02-01
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多