【问题标题】:C. The difference between realloc in double array and char arrayC. double数组和char数组中realloc的区别
【发布时间】:2020-03-17 10:32:51
【问题描述】:

我必须动态增加双精度数组的长度。我知道,如何用 char 数组来做,所以我尝试了这个:

int main() {
    char * tmp = NULL;
    for (int i = 1; i <= 4; i++) {
        tmp = realloc(tmp, i * sizeof(char));
        tmp[i] = 'i';
    }
    puts("char OK");
    double * tmp1 = NULL;
    for (int i = 1; i <= 4; i++) {
        tmp1 = realloc(tmp1, i * sizeof(double));
        tmp1[i] = 0;
    }
    return 0;
}

第一个数组工作正常。但是第二个被消息realloc(): invalid next size粉碎。

这是我的两个问题:

  1. 为什么这种方式在双数组中不起作用?
  2. 如何动态增加双精度数组的大小?

更新: 删除了一个错字

【问题讨论】:

  • 你认为i * sizeof(double) 是什么时候i0,当你尝试tmp1[i] = 0; 时会发生什么?
  • 抱歉,打错了。但无论如何,在重新分配期间仍然会发生错误
  • 不要在此处重新输入您的代码,而是粘贴您的实际代码。
  • @Yoskutik 效果是一样的:如果你分配了i * &lt;element size&gt;array[i] 不存在并且访问它是未定义的行为。

标签: c arrays memory memory-management realloc


【解决方案1】:

TL;DR:两个 sn-ps 都是错误的,第一个 似乎因为 undefined behavior 而工作。

详细地说,问题在于您的索引逻辑。 C 使用基于 0 的索引。因此,在循环中,通过使用

,从i 的值作为1 开始迭代
 tmp[i] = .......

您正在尝试访问无效内存,此时,只有到 tmp[i-1] 的访问才有效。

你需要使用tmp1[i-1] = 0;,同样的。


也就是说,

  1. 在使用返回的指针之前,始终检查内存分配器函数是否成功。
  2. 永远不要使用表单

      pointer = realloc (pointer, ......)
    

    因为,如果realloc 调用失败,您最终也会丢失原始指针。

    引用C11,第 7.22.3.5 章

    realloc 函数返回一个指向新对象的指针(可能具有相同的 值作为指向旧对象的指针),或者如果新对象不能是空指针 已分配。

    [....] 如果新对象的内存不能 已分配,旧对象不会被释放,其值不变。

    • 始终使用临时指针变量来存储realloc()的返回值,
    • 检查调用是否成功[非空返回值]和
    • 如果需要,然后将其分配回原始变量。

【讨论】:

    猜你喜欢
    • 2020-12-23
    • 1970-01-01
    • 2014-09-10
    • 2014-06-03
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    • 2015-02-04
    相关资源
    最近更新 更多