且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

malloc和calloc与std :: string之间的区别

更新时间:2022-05-31 06:00:27

std::string* pointer = (std::string*) malloc(4 * sizeof(std::string)); 

这只会分配足以容纳4个字符串对象的内存.它不会构造它们,并且在构造之前的任何使用都是不确定的.

This only allocates memory sufficient to hold 4 string objects. It does not construct them, and any use before construction is undefined.

至于为什么它可以与calloc 配合使用: std :: string 的默认构造函数很可能会将所有字段设置为零.可能calloc恰好与系统上的std :: string默认构造相同.相反,较小的malloc()对象可能分配了初始垃圾,因此这些对象处于无效状态

As for why it works with calloc: most likely, the default constructor of std::string sets all fields to zero. Probably calloc simply happens to do the same as std::string default construction on your system. In contrast, small malloc() objects are probably allocated with an initial junk, so the objects are not in a valid state

使用足够大的 malloc()效果类似于 calloc().当 malloc()无法重用先前分配的块(带有潜在的垃圾)时,它将从操作系统请求新的块.通常,操作系统会清除它交给应用程序的任何块(以避免信息泄漏),从而使大型malloc()的行为类似于calloc().

With a big enough malloc() the effect is similar to calloc(). When malloc() can't reuse previously allocated block (with potential junk) it requests new blocks from the operating system. Usually the OS will clear any block it hands to the application (to avoid information leak), making big malloc() behave like calloc().

这不适用于所有系统和编译器 .这取决于编译器如何实现 std :: string ,并且取决于未定义的行为如何使编译器感到困惑.这意味着,如果它今天可以在您的编译器上运行,则可能无法在其他系统或更新的编译器上运行.更糟糕的是,在您的程序中编辑看似无关的代码之后,它可能无法在您的编译器上与您的系统一起工作. 从不依赖未定义的行为 .

This won't work on all systems and compilers. It depends on how the compiler implements std::string and depends on how undefined behavior may confuse the compiler. This means that if it works on your compiler today, it might not work on a different system, or with a newer compiler. Worse, it might stop working on your system with your compiler, after you edit seemingly unrelated code in your program. Never rely on undefined behavior.

最简单的解决方案是让C ++处理分配和构造,然后处理销毁和释放.

The simplest solution is to let C++ deal with allocation and construction, and later with destruction and deallocation. This automatically done by

std::vector<std::string> str_vec(4);

如果您坚持要分配和释放自己的内存(99.9%的时间是个坏主意),则应使用 new 而不是 malloc .与 malloc()不同,使用 new 实际上可以构造对象.

If you insist on allocating and deallocating your own memory (which is a bad idea 99.9% of the time), you should use new rather than malloc. Unlike malloc(), using new actually constructs the objects.

// better use std::unique_ptr<std::string[]>
// since at least it automatically
// destroys and frees the objects.
std::string* pointer = new std::string[4];

... use the pointer ...

// better to rely on std::unique_ptr to auto delete the thing.
delete [] pointer;

如果出于某种奇怪的原因,您仍要使用malloc(99.99%的时间是个坏主意),则必须自己构造和销毁对象:

If for some bizarre reason you still want to use malloc (which is a bad idea 99.99% of the time), you must construct and destruct the objects by yourself:

constexpr int size = 4;
std::string* pointer = (std::string*) malloc(size * sizeof(std::string)); 
for (int i=0; i != size ;++i)
    // placement new constructs the strings
    new (pointer+i) std::string;

... use the pointer ....

for (int i=0; i != size ;++i)
    // destruct the strings
    pointer[i].~string();
free(pointer);