【问题标题】:Malloc doesn't doesn't add new memoryMalloc 不添加新内存
【发布时间】:2018-04-08 23:26:20
【问题描述】:

当我尝试使用 malloc 为数组中的浮点数分配新空间时遇到问题。 我的目标是动态创建数组,并且 malloc 每次我想添加一个新浮点数时为新浮点数添加一个空间。

这是我试图运行的代码,但每次它只分配一个带有 sizeof(float) 的数组,即使变量不断增加。

float *funkcia_e(FILE **subor, int *pocet_cien) {
float *pole_cien;
*pocet_cien = 1;

    while (fgets(nazov, sizeof nazov, *subor) != NULL)
    {
        pole_cien = (float*) malloc((*pocet_cien) * 4);

        fscanf(*subor, "%f", &pole_cien[pozicia++]); //This causes problems

        *pocet_cien = *pocet_cien + 1;
    }
}
int main() {
    int pocet_cien = 1;
    float *pole_cien = NULL;

    funkcia_r(&subor, pole_cien, &pocet_cien);
}

这里是调试记录:https://s.put.re/RR6wqRk.mp4

看来 malloc 实际上破坏了数组,而不是扩展它。有什么想法吗?

【问题讨论】:

  • 负担不起重新分配,因为我必须动态分配数组,重新分配时重新分配会清除数组的内容。
  • 不相关:一般不要投射malloc & 朋友或void * 的结果。
  • “不能重新分配,因为我必须分配......” - 在盲目假设之前阅读文档!
  • 不过,realloc 需要我事先定义数组,这是不允许的。
  • 每个新的malloc() 不会初始化任何数据。此代码会丢弃您之前读取的数据。它还严重泄漏内存。您需要使用realloc(),因为它保留了数组中先前初始化的数据;但是您应该避免在每次重新分配时增加 1 使用的空间——这可能会导致糟糕的(二次)性能。 (您对 realloc()malloc() 所做的事情有相反的理解 - '看来 malloc 实际上破坏了数组,而不是扩展它' 是错误的;malloc() 分配新空间,而 @ 987654330@ 扩展旧空间)。

标签: c arrays pointers malloc


【解决方案1】:

您需要使用realloc。它做你想让malloc 做的事情,即让你扩展之前分配的块。相比之下,malloc 是一次性交易:你得到了你的内存块,这就是你必须处理的。

(来自评论)负担不起realloc,因为我必须动态分配数组,realloc 在重新分配数组时会清除数组的内容。

这不是真的:当realloc 扩展分配给您的程序的内存量,并决定它必须重新分配块时,它复制当前块的内容到新块,直到旧块的分配大小,所以新块可以使用了。因此,您当前的程序会导致内存泄漏。

为了让main使用分配结果,你必须通过指针传递指针pole_cien,即float**。否则在funkcia_e 内分配它的结果不会传播到main

需要考虑的其他几点:

  • 不要投射malloc 结果
  • 不要将float 的大小硬编码为4;使用sizeof(float)
  • 确保pocet_cien 从零开始,并用它代替pozicia;在呼叫realloc 时添加1

【讨论】:

  • 本着“先做好,再做快”的原则,这很好。然后应该升级代码,以便它不会在每次迭代时将空间量增加一个float。例如,它应该将分配的空间量加倍,跟踪分配的内容和单独使用的内容。这有助于避免二次复制行为。
【解决方案2】:

这很明显,因为 malloc 不会“添加”任何内存,而是分配一个新的内存块 - 每次都是新鲜的。因此,最终您访问未分配的内存,并且随着索引一直在增加而出现内存故障,但是您为 4 个元素分配了空间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-01
    • 2016-02-13
    • 2016-02-09
    • 2010-12-09
    • 2012-12-26
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多