是否可以在不搜索malloc语句的情况下找到分配给指针的内存

发布于 2024-11-03 22:02:21 字数 416 浏览 1 评论 0原文

假设我已将内存分配给函数 foo 中的某个指针:

void foo()
{    
    // ...  
    int *ptr = malloc(20*sizeof(int));  

    bar (ptr);
}  

foo() 中,我将此指针传递给 bar() ,比方说从 bar() 到另一个函数。

现在,在某个时间点,我想检查: 为指针分配了多少内存。

有没有可能的方法,无需搜索语句:

int *ptr = malloc(20*sizeof(int)); 

使用 GDB 找出分配给指针的内存量?

谢谢。

Suppose I have allocated memory to some pointer in a function foo:

void foo()
{    
    // ...  
    int *ptr = malloc(20*sizeof(int));  

    bar (ptr);
}  

From foo(), I pass this pointer to bar() and let's say from bar() to another function.

Now, at some point of time, I want to check: How much memory was allocated to the pointer.

Is there any possible way, without searching for the statement:

int *ptr = malloc(20*sizeof(int)); 

to figure out how much memory is allocated to the pointer, using GDB?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

椒妓 2024-11-10 22:02:21

答案是:这取决于

许多系统提供 msize() [1]、malloc_usable_size() [2] 或类似函数。如果您使用的是这样的系统,您只需要 (gdb) print malloc_usable_size(ptr) 即可。

2023 更新:

msize() 文档已失效,但 _msize() 仍然可用。

[1] http://msdn.microsoft。 com/en-us/library/z2s077bc(v=vs.80).aspx
[2] http ://www.slac.stanford.edu/comp/unix/package/rtems/doc/html/libc/libc.info.malloc.html

The answer is: it depends.

Many systems provide msize() [1], malloc_usable_size() [2], or similar function. If you are on such a system, (gdb) print malloc_usable_size(ptr) is all you need.

2023 Update:

msize() documentation is dead, but _msize() is still available.

[1] http://msdn.microsoft.com/en-us/library/z2s077bc(v=vs.80).aspx
[2] http://www.slac.stanford.edu/comp/unix/package/rtems/doc/html/libc/libc.info.malloc.html

比忠 2024-11-10 22:02:21

一般来说,没有。 C 没有提供获取已分配内存块大小的方法。您需要跟踪您自己分配了多少内存。

但是,在某些 C 库上,有一个函数可以获取内存块的可用大小 - malloc_usable_size (在 Linux 系统上位于 中,带有不联机帮助页)。请注意,这并不适用于所有 libc,并且可能报告的值大于您请求的值。请仅将其用于调试。

为了完整起见,我最初的答案深入探讨了低级堆元数据,在 @Employed Russian 指出 malloc_usable_size 之前:

但是,您可以手动提取它。但请注意,这一切可能会因操作系统、CPU 架构和 C 库的不同而有所不同。我假设您使用的是eglibc 2.12.1;在其他地方,您的结果可能会有所不同。

警告:说真的,除了在 gdb 中调试之外,不要使用它。真的。我是认真的。

glibc 内存分配器像这样存储内存块(来自 malloc/malloc.c):

    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             Size of previous chunk, if allocated            | |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             Size of chunk, in bytes                       |M|P|
      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             User data starts here...                          .
            .                                                               .
            .             (malloc_usable_size() bytes)                      .
            .                                                               |
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             Size of chunk                                     |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

您的数据位于此处的“mem”,块的大小包括标头。 P 标志指示前一个块数据是否有效,M 指示这是一个 mmap 映射(对于大型 malloc)。所有这些都不太重要;重要的是该大小在内存之前存在一个指针大小的增量;您只需屏蔽这些标志并减去标头大小:

Breakpoint 1, main () at test.c:8
8               char *a = malloc(32);
(gdb) n
10              free(a);
(gdb) print (*((unsigned long long*)a - 1) & ~3) - sizeof(unsigned long long)*2
$14 = 32

警告:实际分配的大小可能比您请求的大。不要试图变得聪明并使用多余的东西。一开始就询问您需要多少。

注意事项 2:这只适用于 glibc。它仅适用于某些版本的 glibc。因此可能会在没有任何警告的情况下随时破裂。我怎么强调都不为过; 不要在您的实际代码中使用它;仅用于当您用尽所有其他选项时进行调试。您的代码需要自行跟踪其缓冲区大小。

In general, no. C doesn't provide a way to get the size of an allocated block of memory. You need to keep track of how much memory you allocated yourself.

BUT, on some C libraries, there is a function to get the usable size of a block of memory - malloc_usable_size (found in <malloc.h> on Linux systems, with no manpage). Note that this does not work on all libcs, and may report a value larger than you requested. Please, use it only for debugging.

For completeness, my original answer, which dives into the low-level heap metadata, prior to @Employed Russian pointing out malloc_usable_size:

BUT, you may be able to extract this manually. Note, however, that this all can vary depending on your OS, CPU architecture, and C library. I will assume you're using eglibc 2.12.1; your results may vary anywhere else.

WARNING: Seriously, DO NOT use this except for debugging in gdb. Really. I mean it.

The glibc memory allocator stores chunks of memory like this (out of a doc comment in malloc/malloc.c):

    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             Size of previous chunk, if allocated            | |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             Size of chunk, in bytes                       |M|P|
      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             User data starts here...                          .
            .                                                               .
            .             (malloc_usable_size() bytes)                      .
            .                                                               |
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             Size of chunk                                     |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Your data is at 'mem' here, and the size of chunk includes the header. The P flag indicates whether the previous-chunk data is valid, and M indicates this is a mmap mapping (for large mallocs). All of that isn't too important; what's important is that the size lives one pointer-sized increment before your memory; you just have to mask out those flags and subtract the header size:

Breakpoint 1, main () at test.c:8
8               char *a = malloc(32);
(gdb) n
10              free(a);
(gdb) print (*((unsigned long long*)a - 1) & ~3) - sizeof(unsigned long long)*2
$14 = 32

Caveat: The actually allocated size may be larger than you requested. Don't try to get smart and use the excess. Ask for how much you need at the start.

Caveat 2: This only works with glibc. And it only works with certain versions of glibc. and thus may break at any moment without any warning. I can't stress this enough; DO NOT use this in your actual code; only for debugging when you have exhausted every other option. Your code needs to keep track of its buffer sizes on its own.

波浪屿的海角声 2024-11-10 22:02:21

。当您使用 malloc() 时,您必须自己存储该信息。

No. You have to store that information yourself when you malloc().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文