【问题标题】:How do I calculate end address of memory block allocated by malloc?如何计算malloc分配的内存块的结束地址?
【发布时间】:2011-11-20 20:04:26
【问题描述】:

我们都知道 malloc 返回分配的内存块的起始地址,但我想我如何计算这个块的结束地址

  int *p, *q;
  p=malloc(4*sizeof(int));
  q=p+4;

现在q 将指向结束地址块,但我想有一些其他方法来获取 malloc 分配的内存块的结束地址。

编辑

我想知道的另一件事是有办法确保我们处于分配块的末尾

【问题讨论】:

  • 其实你没有。 4*sizeof(int) 在几乎任何现代系统上都会产生 16。所以 +8 不会起作用。
  • p 指向分配的内存结束后很远。在大多数情况下,您需要添加4(即使我认为它是实现定义的)。为什么你需要其他方法呢?
  • @halfdan:你说得对,但似乎是出于错误的原因。 +8 将使指针前进 8*sizeof(int) 个字节。
  • 既然你知道你已经分配了4ints 的内存,你可以做p += 4。但最好复制p,这样你以后可以free
  • @pmg 好的,我读到了。 p+4 很好,但 p+5 是 UB。因此,该标准特别允许您指向末尾的 1。这是非常明智的。

标签: c malloc


【解决方案1】:

您不能使用标准技术,仅使用指针作为输入来确定块的末尾在哪里。为了做到这一点。您将不得不检测您的分配器或使用提供此类功能的分配器。

当您使用malloc 分配内存时,程序员完全有责任跟踪您分配了多少内存。您不能在稍后的某个时间点要求系统告诉您有关内存块的任何信息。

【讨论】:

  • @davis 有没有办法确保我们已经到达内存块的末尾?
  • 这个问题是什么意思?
  • 假设有些人在做指针运算时犯了一个错误(在这种情况下是 p=p+8),那么有什么办法可以从中恢复。
  • @Amit 不,C 中没有范围检查或容错的规定。你必须编写没有缺陷的代码。这很难。
  • 这是为我们的 valgrind 准备的。
【解决方案2】:

您编写的代码 (p=p+8) 将使 p 指向末尾,因为您为 4 个整数分配了空间,但将指针移动了 8 个整数(整数,而不是字节)。

一种方法很简单:

size_t const SIZE = 4;
int *p;
p=malloc(SIZE*sizeof(int));
p=p+SIZE;

现在,没有错误,未来也不可能出现。

【讨论】:

    【解决方案3】:

    如果你只是想知道你要求多少空间,那你就不走运了,因为这不是malloc(3)'合同的一部分。 malloc 的一些特定实现支持为此提供 API,但它不是可移植的。

    所以,除非你自己写malloc,否则你不能。

    如果你真的想知道分配的内存总量,那你就更不走运了。如果malloc 为大小q 返回值p,则存储可以从任何p-X 开始并扩展到p-X+q+Y,对于malloc 的实现者认为方便他们的任何X 和Y 值自己的开销。

    检测指针使用错误的正确方法是使用 valgrind 之类的工具。

    【讨论】:

    • X 和 Y 在哪里出现?如果malloc(q) 返回p,则内存从p 开始并在此评论中扩展到p+q-1(我的指针是char*)。
    • 当 malloc 返回 p 时,它通常会在 p 之前分配一些字节的开销,然后可能会分配一些保护。
    • 当然可能有块头,但那都是私有的。访问它是 UB。
    • @DavidHeffernan 我最初理解这个问题是关于私人开销,而不是“哎呀,我忘了写下我分配的内容”。
    • 是的,我也花了一段时间才弄清楚被问到的确切内容。
    【解决方案4】:

    答案稍晚,但我认为这需要提及: 对于 Visual Studio,您可以使用 _msize() 来计算提供给 malloc() 的数字(或 new x 分配的字节数,如果您使用的是 C++)。它只适用于在堆上分配的指针,所以_malloca()alloca()char x[2]; 不起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-27
      • 2018-08-03
      • 1970-01-01
      • 1970-01-01
      • 2015-06-14
      • 2016-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多