Tin*_*lam 1 c++ malloc stdstring calloc
我最近进入了C++,我遇到了使用malloc的问题.下面的代码不会打印出"成功"(程序崩溃,退出代码为0xC0000005),而如果我使用calloc,则一切正常.
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;
}
Run Code Online (Sandbox Code Playgroud)
以下代码有效.
calloc(4, sizeof(std::string));
Run Code Online (Sandbox Code Playgroud)
如果我分配正常数量的12倍,Malloc也可以工作.
有人可以解释这种行为吗?这与std :: string有关吗?
std::string* pointer = (std::string*) malloc(4 * sizeof(std::string));
Run Code Online (Sandbox Code Playgroud)
这仅分配足以容纳4个字符串对象的内存.它不构造它们,并且在构造之前的任何使用都是未定义的.
编辑:至于它为何与calloc一起工作:最有可能的是,默认构造函数 std::string将所有字段设置为零.可能calloc恰好和你系统上的std :: string默认构造一样.相反,小的malloc()对象可能分配了初始垃圾,因此对象不处于有效状态
足够大malloc()的效果类似于calloc().当malloc()无法重用先前分配的块(具有潜在垃圾)时,它从操作系统请求新块.通常操作系统会清除它对应用程序的任何阻止(以避免信息泄漏),使大malloc()的行为类似于calloc().
这不适用于所有系统和编译器.它取决于编译器如何实现,std::string并取决于未定义的行为如何混淆编译器.这意味着如果它今天适用于您的编译器,它可能无法在不同的系统上运行,或者使用较新的编译器.更糟糕的是,在编辑程序中看似无关的代码后,它可能会停止使用编译器在您的系统上运行.永远不要依赖未定义的行为.
最简单的解决方案是让C++处理分配和构造,然后再进行破坏和释放.这自动完成了
std::vector<std::string> str_vec(4);
Run Code Online (Sandbox Code Playgroud)
如果你坚持分配和释放自己的内存(99.9%的时候这是一个坏主意),你应该使用new而不是malloc.不像malloc(),使用new实际构造对象.
// 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;
Run Code Online (Sandbox Code Playgroud)
如果由于某些奇怪的原因你仍然想使用malloc(99.99%的时候这是一个坏主意),你必须自己构造和破坏对象:
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);
Run Code Online (Sandbox Code Playgroud)
有人可以解释这种行为吗?
在这两种情况下,行为都是不确定的.calloc似乎工作的案件仅仅是因为运气不好.
为了在分配的内存空间中使用对象,必须首先构造对象.你从未构造任何字符串对象.
构造动态分配的对象数组的最简单方法是使用向量:
std::vector<std::string> vec(4);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
342 次 |
| 最近记录: |