calloc vs new 用于各种编译器中的复杂结构
Posted
技术标签:
【中文标题】calloc vs new 用于各种编译器中的复杂结构【英文标题】:calloc vs new for complicated structs in various compilers 【发布时间】:2017-11-09 13:50:39 【问题描述】:我有以下结构:
struct MyNewShinyStruct
int index;
std::string name;
;
当calloc
上面的结构然后给name
赋值时:
char letters[128]"ABCDEFG";
auto temp = static_cast<MyNewShinyStruct*>(calloc(2, sizeof(MyNewShinyStruct)));
temp[0].name = letters;
我应该为上述问题遇到麻烦:-)(我应该使用new
运算符)。 'calloc' 将分配的内存清零,并且不调用 struct/std::sting 的构造函数。但是,由于某些未知原因,上述代码在 VS2010/2013/2015 中有效,仅在 VS2017 中失败。它应该总是失败!请问我错过了什么?
附: 上面的代码已经投入生产(使用 VS2010 编译)多年,甚至没有一次报告与此代码有关的错误,甚至一次都没有。它总是有效的。
【问题讨论】:
calloc
单独创建非 pod 类型是不够的。 std::string
不是 pod,通过扩展,MyNewShinyStruct
也不是。结果是未定义的行为,无法进行有意义的推理。
未定义的行为并不意味着总是失败。有时它似乎也有效。
它是 C++,使用 std::vector!
您在演示中遗漏的部分是在分配该字符串后打印该字符串的内容。在 Visual Studio 2017 中,它会导致垃圾。
它真的总是有效运气不好。现在开始修复它。
【参考方案1】:
它应该总是失败!请问我错过了什么?
您忽略了 UB 并不意味着“总是失败”这一事实。它可以是任何东西,包括预期的行为。要修复您的程序,请在 calloc 返回的内存上使用placement new(假设您出于某种原因必须使用calloc,如果您不使用std::vector
代替)。您还应该了解std::string
很可能会自行分配内存,除非您提供自定义分配器,否则不太可能 calloc。
【讨论】:
1.我们UB
是什么?
@RefaelSheinker 未定义行为。
To fix your program use placement new on the memory returned by calloc
- 这是一种选择。但我可能会用new
完全替换calloc
并完成它,
@RefaelSheinker 你最好使用std::vector
,或者至少使用带有new
的智能指针
@RefaelSheinker ideone.com/eNQZjc 然后使用placement new .. 注意:您必须手动调用析构函数.. 您让自己更加头疼.. 即使是传统的C++ 也不需要malloc 或 calloc。它是 C++,使用新的。以上是关于calloc vs new 用于各种编译器中的复杂结构的主要内容,如果未能解决你的问题,请参考以下文章
C ++中的“new”和“malloc”和“calloc”有啥区别? [复制]
动态分配数组时的C ++ new vs new [] [重复]