gpt4 book ai didi

c - malloc 实际分配了多少内存,并且可以将变量存储在分配有 malloc 的数组中以节省内存?

转载 作者:行者123 更新时间:2023-11-30 21:19:15 30 4
gpt4 key购买 nike

关闭。这个问题需要更多 focused .它目前不接受答案。












想改进这个问题?更新问题,使其仅关注一个问题 editing this post .

3年前关闭。




Improve this question




假设我有一个具有以下形式的结构

typedef struct A
{
double one;
double two;
void *some_ptr;
uint8_t *array_ptr;
}

这个结构在我的系统上大小为 32 字节。我有一个 uint8_t 变量,我想添加到这个结构中,但是,内存非常宝贵(这些结构中会有很多)。

因此,我不想做以下事情,因为它会将我的内存使用量增加到 40 字节。
typedef struct B
{
double one;
double two;
void *some_ptr;
uint8_t *array_ptr;
uint8_t my_value;
}

我想知道的是,如果我向数组添加一个额外的索引(所有数组的大小都相同,但是,直到运行时我才知道大小)如果我可以减少我正在使用的内存量40 到 33 个字节(数组将使用 malloc 分配)。

当调用 malloc 时,它应该返回等于一页的内存量,尽管我只保证可以访问我请求的内存量(如果我错了,请纠正我)。考虑到这一点,我的问题可以归结为以下几点:

如果我使用 malloc 为数组分配一个额外的字节并将我的变量存储在数组的末尾而不是结构中自己的变量,我会节省内存吗?我问这个问题是因为我不清楚 malloc 将实际分配多少内存。例如,如果我要求它为一个数组提供 10 个字节,我是保证得到 10 个字节还是 16 个字节(64 位系统)?如果我要求它为两个数组两次给我 10 个字节,我会得到 20 个字节、32 个字节还是 24 个(24 个,因为总数必须是 8 个字节)?因为 malloc 应该返回的指针是 8 的倍数,所以我相信答案是 32,但我不确定(如果是这种情况,那么在最坏的情况下,我会得到与向结构中添加变量相同的内存使用情况) .这个问题的另一种表述方式是,如果我使用 malloc 分配 X 字节,实际使用了多少字节?

笔记:
以前有人问过与我类似的问题,但我不相信他们解决了我实际问的问题。 IE。
https://stackoverflow.com/questions/5213356/malloc-how-much-memory-has-been-allocated

https://stackoverflow.com/questions/25712609/how-much-memory-does-calloc-actually-allocate

最佳答案

How much memory does malloc actually allocate?



这未指定,是 实现特定 .您可以深入研究 C 标准库(例如 GNU libcmusl-libc )的现有自由软件实现的源代码,以了解它们的表现如何 malloc .另外, malloc可能会失败(参见我的 joke-implementation,它非常快),你应该对此进行测试。

根据经验, malloc至少出于记账目的可能会多使用一个字,并将分配的内存对齐到可能的两个字(例如 x86-64 上的 16 个字节)。但细节是实现和 ABI具体的。由于有一些开销,您可能更喜欢 malloc几个大的内存区域(例如每个几十千字节)而不是许多小的内存区域(每个十几个字节)。

I have a single uint8_t variable that I would like to add to this struct, however, memory is at a premium (there are going to be A LOT of these structs).



你确定内存有那么重要吗?大多数计算机都有许多千兆字节的内存,并且大多数(但不是全部)应用程序并不是非常饥饿。在嵌入式世界中,情况有所不同(有时甚至不允许您使用任何 malloc );但是,Linux 计算机在嵌入式情况下也很常见(例如,我上类乘坐的公共(public)汽车有一个由某些 Linux x86 系统驱动的显示器 - 有时当磁盘关闭时会出现 GRUB 屏幕)。

您可以考虑分配您的 struct A 的大型数组。 .您可以考虑在一个巨大的数组中使用索引,而不是指针。然后您可以考虑分配 my_value在另一个数组中,等等。

您甚至可以编写自己的代码 malloc .通常你不应该,因为现有的 malloc实现都经过了很好的调整。您可以选择其他 malloc实现(例如 tcmalloc )

For example, if I ask it to give me 10 bytes for one array, do I get ten bytes or 16 guaranteed (64 bit system)?



您可能会消耗至少 16 个字节,并且可能会消耗 32 个字节。但这是特定于实现的。 Linux 有 mallinfo(3)malloc_stats(3)和其他类似的功能来查询您的进程的状态。和 proc(5)你可以在 Linux 上获得更多关于它的信息。例如,如果您的 Linux 进程的 pid 为 1234,请查看 /proc/1234/maps/proc/1234/status在它运行时。另见 this Linux特定的答案。

不要忘记您的开发时间也是如此。您自己一天的工作可能比在桌面上添加更多 DDR4 RAM 花费更多。

然而,有一些利基应用程序和领域(特别是 HPC、大数据、基因组学……),熟练的开发人员需要花费数月的时间才能适应 TB 级计算机服务器。

您可以使用内存领域(旧 GNU obstacks 可能会很有启发性)。可以查询 struct的大小与 sizeof并与 alignof 对齐.您可能想阅读 GC handbook (即使在 C 中编写手动内存管理代码时),因为 garbage collection 的术语和概念与您的问题相关(因为内存消耗是整个程序的属性)。

你可以绕过 malloc并直接使用 operating system原语(即 system calls )来增加您的 virtual address space .在 Linux 上,您将使用 mmap(2) (或过时的 sbrk(2) )和 munmap .当然 malloc在内部使用它们: malloc使用 mmap 获取内存页面(至少 4 KB)并使用 munmap 释放它们.通常 free -d 内存区域被保留并在以后被 future 重用 malloc s。

关于c - malloc 实际分配了多少内存,并且可以将变量存储在分配有 malloc 的数组中以节省内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53755810/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com