如何计算malloc分配的内存块的结束地址?

如何计算malloc分配的内存块的结束地址?,c,malloc,C,Malloc,我们都知道malloc返回分配内存块的开始地址,但我想知道如何计算这个块的结束地址 int *p, *q; p=malloc(4*sizeof(int)); q=p+4; 现在q将指向结束地址块,但我想使用其他方法来获得malloc分配的内存块的结束地址 编辑 还有一件事我想知道,这里有一种方法可以确保我们在分配的块的末尾您编写的代码(p=p+8)将p指向末尾之外,因为您为4个整数分配了空间,但将指针移动了8(整数,而不是字节) 一种方法很简单: size_t const SIZE

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

  int *p, *q;
  p=malloc(4*sizeof(int));
  q=p+4;
现在
q
将指向结束地址块,但我想使用其他方法来获得malloc分配的内存块的结束地址

编辑

还有一件事我想知道,这里有一种方法可以确保我们在分配的块的末尾

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

一种方法很简单:

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

现在,没有bug,将来也不会有bug。

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

因此,除非您编写自己的
malloc
,否则您不能这样做

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


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

使用标准技术,仅使用指针作为输入,无法确定块的结束位置。为了做到这一点。您必须为您的分配器插入指令或使用提供此类功能的分配器


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

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

实际上你不起作用。
4*sizeof(int)
将在几乎任何现代系统上产生16。所以+8不起作用。
p
在分配的内存结束后很远。在大多数情况下,您需要添加
4
(尽管我认为它是实现定义的)。“你为什么需要其他方法来解决这个问题呢?”哈夫丹:你说得有点对,但似乎是出于错误的原因。+8将指针向前移动8*sizeof(int)字节。因为您知道已经分配了
4
int
s内存,所以可以执行
p+=4
。但最好是复制
p
,这样你以后就可以
免费
了。@pmg好的,我读过了<代码>p+4
可以,但
p+5
可以。因此,该标准特别允许您指向结束后的1。这是非常明智的。@davis有没有办法确保我们已经到达内存块的末尾?这个问题是什么意思?假设有人犯了一个错误(在本例中是p=p+8),就像我在做指针算术时犯的那样,那么有没有办法从中恢复过来。@Amit没有,在C语言中没有范围检查或容错的规定。您必须在C语言中编写没有缺陷的代码。这很难。这是为了我们的valgrind。X和Y从何而来?如果
malloc(q)
返回
p
,则内存从
p
开始,并扩展到
p+q-1
(我的指针是
char*
)在这个注释中。当malloc返回
p
时,它通常在p之前分配了一些字节的开销,之后可能分配了一些保护。当然可能有块头,但这都是私有的。访问它是UB。@DavidHeffernan我最初理解这个问题是关于私人开销的,而不是“天啊,我忘了写下我要写的东西”。是的,我花了一段时间才弄清楚到底问了什么。