【问题标题】:How does realloc work on memory allocated using calloc?realloc 如何在使用 calloc 分配的内存上工作?
【发布时间】:2015-10-31 14:39:12
【问题描述】:

当我们尝试使用realloc 调整malloc 分配的内存大小时,我们通常会这样做:

char *ptr = (char *)malloc(size_1);
ptr = (char *)realloc(ptr, size_2);

如果size_2 可能大于或小于size_1。如果新大小更大,则旧数据不会丢失,并且新分配的字节未初始化。如果旧地址没有足够的内存来连续存储所有字节,ptr 包含的起始地址可能会更改。 realloc 将旧块的内容移动到新块中,ptr 将指向这个新块的初始字节。

但是,如果使用calloc 分配内存,我无法理解realloc 函数的作用。有人可以简要介绍一下realloc 如何处理calloc 分配的内存吗?

【问题讨论】:

  • 可能对 OP 没有功能差异的细微差异:1) 如果分配了更多内存,则不知道将额外的内存初始化为 0 - 初始值未定义。最初分配给calloc() 的内存在第一次访问之前被清零,尽管不一定在calloc() 时间。 2) calloc() 可以分配比malloc()/realloc() 更多的内存,因为calloc() 调用仅限于理论上的SIZE_MAX*SIZE_MAX。这发生在早期的平台上 - 现在看不到。
  • 为什么会有这么多以“我们知道”开头的帖子
  • @MattMcNab 确实,但 OTOH 让我们庆幸的是,潜在的谬误或错误前提在开始时经常出现:-|
  • @DivyaBolla 当您编辑了第一句话时,您现在已经完全删除了引发问题的唯一内容。如果您现在了解内存布局没有什么不同,那么问题的意义何在?

标签: c malloc dynamic-memory-allocation realloc calloc


【解决方案1】:

我们知道 malloc 和 calloc 的内存块布局是不同的。

不,我们没有。实际上,我们知道这根本没有区别,除了 calloc() 负责将其参数相乘(以确定块大小)并确保分配的块以全零位模式初始化。

其余的如下。 realloc() 处理内存块的方式没有区别,无论使用什么函数分配它。 realloc() 处理 calloced 块的方式与处理 malloc()ed 块的方式完全相同。

【讨论】:

  • 当我们使用 malloc 请求单个连续内存块时,我们使用 calloc 请求多个连续内存块。我们如何使用 realloc 请求新的内存块?如果我们尝试更改的内存是使用 calloc 分配的,我对 realloc 函数参数有点困惑
  • 使用calloc(),您可以获得一个内存块,就像使用malloc() 和使用realloc() 一样。
  • @Divya Bolla:该语言没有“几个连续的内存块”的概念。产生这样的东西的唯一方法是分配一个组合大小的块。因此,calloc 分配了一个内存块。它只负责将参数nmembsize(按照C11 命名)相乘,以计算单个块的大小。还有一个微妙的问题是确保乘法不会溢出(如果我没记错的话,calloc 也负责确保这一点)。
【解决方案2】:

malloc 和 calloc 的内存块布局不同

其实没有。callocmalloc的区别是——

  calloc() initializes the allocated memory with 0 value.

  malloc() initializes the allocated memory with garbage values.

以及其中的参数数量。

我不认为realloc 对待malloccalloc 分配的内存不同。

编辑

关于你的问题-

a=calloc(5,sizeof(int));

if(a==NULL)
 {
    printf("Error in allocating memory");
  }
a=realloc(a,7);  // also check its return.

这将按预期工作。

【讨论】:

  • char *ptr = calloc(5,sizeof(char));现在我需要 7 个块,每个块大小为 char.. ptr=(char *)realloc(ptr, );我们应该在 中给出什么参数?
  • @DivyaBolla:你可以使用7 * sizeof(char),但我只会写7。并且您不需要转换由 realloc 返回的 void* ,就像您需要转换由 calloc 返回的 void* 一样。
  • @DivyBolla 7*sizeof char,当然。有什么问题?而且它不是“每个大小为 char 的 7 个块”,而是 一个 大小为 7 个字符的块。
  • @DivyaBolla 我认为你想多了。请查看编辑。
【解决方案3】:

我们知道 malloc 和 calloc 的内存块布局是不同的。

没有。这是相同的。这种说法没有根据。

当我们尝试使用 realloc 调整 malloc 分配的内存大小时,我们通常会这样做:

char *ptr=(char *)malloc(size_1); ptr=(char *)realloc(ptr, size_2);

[where] size_2 可能大于或小于 size_1。如果新大小更大,则旧数据不会丢失,并且新分配的字节未初始化。如果旧地址没有足够的内存来连续存储所有字节,则 ptr 包含的起始地址可能会更改。

正确。

realloc 将旧块的内容移动到新块中

如有必要。如果块只是增长,则不需要此步骤。

而 ptr 将指向这个新块的初始字节。

正确。

但是,如果使用 calloc 分配内存,我无法理解 realloc 函数的作用。

同样的。

谁能给我一个简要的概述 abt realloc 对 calloc 分配的内存的作用?

是一样的。

你想多了。 calloc(n, size) 可以通过 malloc(n*size) 后跟 memset() 来实现。 realloc() 不在乎。

【讨论】:

  • "calloc(n, size) 只不过是 malloc(n*size) 后跟 memset()。 - 在抽象机器中确实如此。一些实际的实现以不同的方式实现 calloc,这可能会让 OP 感到困惑。
  • @MattMcNab 很难看出怎么做。他将无法看到它是如何实现的,如果可以的话,他不需要问这个问题。我也很困惑他怎么会认为 7 个相邻的 1 个字符宽的内存块可能有任何内部格式,但这是另一个问题。
猜你喜欢
  • 2019-11-11
  • 1970-01-01
  • 2020-05-01
  • 2023-03-11
  • 2016-07-04
  • 2017-01-12
  • 2013-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多