malloc和calloc与std :: string之间的区别 [英] Difference between malloc and calloc with std::string

查看:200
本文介绍了malloc和calloc与std :: string之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始使用C ++,在使用malloc时遇到了问题.下面的代码不会打印出成功"(程序崩溃,退出代码0xC0000005),但是如果我使用calloc,则一切正常.

I have recently gotten into C++ and I've encountered a problem working with malloc. The code below does not print out "Success" (Program crashes with exit code 0xC0000005) whereas if I use calloc instead everything works fine.

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

    for(int i = 0; i < 4; i++){
        pointer[i] = "test";
    }

    std::cout << "Success" << std::endl;

    return 0;
}

下面的代码有效.

calloc(4, sizeof(std::string));

如果我的分配是正常数量的12倍,则Malloc也可以工作.

Malloc also works if I allocate like 12 times the normal amount.

有人可以解释这种行为吗?这与std :: string有关吗?

Can somebody explain this behavior ? Does this have something to do with std::string ?

推荐答案

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);

这篇关于malloc和calloc与std :: string之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆