当我尝试理解C / C ++中的内存分配时,我遇到了一个问题,我知道函数malloc()
将分配堆类型的区域,{{{ 1}}在C ++中,所以我编写了以下代码:
new
我使用char *a;
a = (char *)malloc(8);
a [0] = 'a';
char *b;
b = new char[8];
char *c;
c = (char *)malloc(8);
c [0] = 'b';
编译并使用g++ -g
查看运行时的状态,并获得以下结果:
gdb
和
(gdb) i locals
a = 0x804b008 "a"
b = 0x804b018 ""
c = 0x804b028 "b"
正如我们所看到的,两个(gdb) x/48b a
0x804b008: 97 0 0 0 0 0 0 0
0x804b010: 0 0 0 0 17 0 0 0
0x804b018: 0 0 0 0 0 0 0 0
0x804b020: 0 0 0 0 17 0 0 0
0x804b028: 98 0 0 0 0 0 0 0
0x804b030: 0 0 0 0 -47 15 2 0
之间还有一行 8字节,我不知道为什么这行存在,请告诉我是什么它
答案 0 :(得分:3)
17值可能没有特别的意义,它肯定不是你的记忆区域的一部分,或者你应该从你的程序中读取或写入的东西。当您使用malloc
时,返回的内存可能在使用之后被某些先前的malloc
释放,因此其中包含旧数据。请求的内存量可以四舍五入到malloc
系统更喜欢处理的某个大小 - 例如16,所以你可能会或者可能不会“拥有”那些额外的8个字节,即{{1}总是会给你它们而不是把你转移到其他一些内存区域(但无论如何,如果你试图在这样的realloc
之前读取/修改它们,那么它是未定义的行为)。 realloc
库使用周围的内存进行自己的簿记也是合法的,并且8字节分配之间的内存可能仍被其他库/引导代码使用。只有你明确拥有的8字节区域中的字节/字符,你明确地用自己的内容覆盖,才有可预测的内容。
请注意,对于malloc
,请求将数组元素初始化为'\ 0'的语法不同:
new
答案 1 :(得分:2)
Malloc(和new)只是分配连续的地址块供您使用。它们不保证未分配的地址中发生的情况。此内存可用于数据结构以跟踪已分配的内容。它可能只是未使用的内存,可能会在以后的malloc或realloc调用中使用。它可能永远不会被使用,或者它可能已被您明确或隐式调用的某个库使用。
答案 2 :(得分:2)
在你的记忆转储中,你拥有" 24字节(3 x 8字节),但显示48字节(6 x 8字节)。我已经贴上了"你的"什么不在这里:
0x804b008: 97 0 0 0 0 0 0 0 <- Yours
0x804b010: 0 0 0 0 17 0 0 0 <- Not yours
0x804b018: 0 0 0 0 0 0 0 0 <- Yours
0x804b020: 0 0 0 0 17 0 0 0 <- Not yours
0x804b028: 98 0 0 0 0 0 0 0 <- Yours
0x804b030: 0 0 0 0 -47 15 2 0 <- Not yours
您正在查看分配&#34;之间的数据。没有定义它将包含什么 - 它没有被任何C或C ++标准定义(例如,特定的C或C ++库可能以某种方式定义它,但C ++库不需要它来记录它这在任何方面)。
在许多C或C ++库中,此区域用于存储有关下一个(免费?)数据所在位置的信息,但对我来说,这并不是这种情况。