C++ 之 new 函数疑问,你们也有这种情况吗?

2020-04-27 15:23:50 +08:00
 sl0000

读取 new 出来的对象占用的连续堆内存,偶然发现时有时无的存在一些脏数据,但是通过栈内存分配的对象不会存在脏数据。脏数据的出现与内存对齐优化有关。

new 函数并不会把 sizeof(Cls)的连续内存全部清空,只会清除使用到的内存,内存对齐的空置的内存并不会被清零。

class Cls {
Public;
    long a;
    char b;
    long c;
    char d;
};

char s[256] = {};
for (int i = 0; i < 256; i++) {
    s[i] = 0xff;
}

Cls * pa = new  (s) Cls {1,2,3,4};

(lldb) memory read --size 4 -format x --count 64 pa

用的 Xcode,这种情况是所有平台都会出现吗?如果是,那么这种设计是为什么?

Cls * pa = new  (s) Cls ();

经提醒,我改为默认构造函数确实是都被清零了。

2235 次点击
所在节点    C++
8 条回复
felix021
2020-04-27 15:34:16 +08:00
估计 C++规范对 placement new 没有做内存清零的要求,具体做不做就看编译器的实现了。

ref: https://stackoverflow.com/questions/10490191/does-placement-new-zero-out-the-memory
felix021
2020-04-27 15:35:06 +08:00
注:不做某件事情,当然是为了更快
dearmymy
2020-04-27 15:49:49 +08:00
感觉跟编译器有关吧,而且你 debug release 估计也不一样,也许 debug 帮你清了。release 就不管你。
不知道你想干啥,你要是嫌弃 new 出来的内存对齐空余部分,可以把内存对齐设置下
sl0000
2020-04-27 15:51:16 +08:00
@dearmymy 主要是因为阅读的时候会被干扰到,一些没有用的数据穿插其中
dearmymy
2020-04-27 15:58:41 +08:00
@sl0000 那构造函数自己清零下,在加上#pragma pack(1) 就不会出现字节对齐间隙了
hu8245
2020-04-27 16:23:00 +08:00
operator new
Wirbelwind
2020-04-28 22:16:27 +08:00
operator new 和 delete 本身不会清除内存数据,因为操作系统底层可能会清除。

我记得 linux 分配新栈时候是会清 0 的。

(某个协程库是分配栈也会清 0,但是重复使用某个栈的时候不会清 0.)
felix021
2020-04-29 00:18:47 +08:00
@dearmymy pragma pack(1) 还是要慎用,可能会导致性能问题

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/666631

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX