C++ 包含vecto的对象的动态分配
我试着这样做:C++ 包含vecto的对象的动态分配,c++,vector,dynamic,allocation,C++,Vector,Dynamic,Allocation,我试着这样做: #include <iostream> #include <vector> using namespace std; struct test{ vector<int> tab; }; int main(){ test* obj2; obj2 = (test*) malloc(sizeof(test)); obj2->tab.push_back(1); obj2->tab.push_
#include <iostream>
#include <vector>
using namespace std;
struct test{
vector<int> tab;
};
int main(){
test* obj2;
obj2 = (test*) malloc(sizeof(test));
obj2->tab.push_back(1);
obj2->tab.push_back(2);
for(int i=0;i<2;i++){
cout<<obj2->tab[i]<<" ";
}
}
#包括
#包括
使用名称空间std;
结构测试{
向量标签;
};
int main(){
测试*obj2;
obj2=(测试*)malloc(sizeof(测试));
obj2->tab.推回(1);
obj2->tab.向后推(2);
对于(int i=0;i
它起作用了
不,它没有。这是不确定的行为似乎起作用
但我不明白为什么
为了理解这(似乎)起作用的原因,我们必须看看std::vector
的结构。一个实现可以使用3个指针:
- 分配内存的开始
- 已用内存结束
- 分配内存结束
现在通过malloc()分配一些字节
并将它们解释为一个包含这3个指针的类。如果我们假设一个指针为4字节大,则分配12个字节,并将前4个字节解释为指向已分配内存开始的指针,后4个字节解释为指向已用内存结束的指针,最后4个字节解释为指向已分配内存结束的指针
如果分配的内存恰好包含合理的值,这可能是有效的。但是它确实是未定义的行为。例如,C++中包含所有的零点,这导致所有三个指针都是代码> NulLPTR < /代码>,这可能也是构造函数所做的。
但是在VisualStudio中,内存没有初始化为零,这导致所有三个指针的随机值,从而导致segfault
那么,为什么这(似乎)起作用呢?因为你分配的内存包含了合理的值,这纯粹是运气使然
我要求一些空向量的内存
不,您只需分配内存并将其解释为一个向量。向量为空(甚至可以工作)只是幸运,如上所述。碰巧向量在调用构造函数后会以相同的状态结束
但是,我在向量中添加了一些东西,所以obj2占用的内存增加了,不是吗
不,它不是。任何对象的大小在编译时都是已知的和固定的。一个std::vector
只管理堆内存,例如动态分配的内存。因此它不会增加它自己的大小,也不会增加包含它的结构的大小,而只是增加它所管理的内存的大小
这仍然是一件好事吗
不,绝对不是。如果您需要动态内存,请使用容器、智能指针或至少new
它起作用了
不,它没有。这是不确定的行为似乎起作用
但我不明白为什么
为了理解这(似乎)起作用的原因,我们必须看看std::vector
的结构。一个实现可以使用3个指针:
- 分配内存的开始
- 已用内存结束
- 分配内存结束
现在通过malloc()分配一些字节
并将它们解释为一个包含这3个指针的类。如果我们假设一个指针为4字节大,则分配12个字节,并将前4个字节解释为指向已分配内存开始的指针,后4个字节解释为指向已用内存结束的指针,最后4个字节解释为指向已分配内存结束的指针
如果分配的内存恰好包含合理的值,这可能是有效的。但是它确实是未定义的行为。例如,C++中包含所有的零点,这导致所有三个指针都是代码> NulLPTR < /代码>,这可能也是构造函数所做的。
但是在VisualStudio中,内存没有初始化为零,这导致所有三个指针的随机值,从而导致segfault
那么,为什么这(似乎)起作用呢?因为你分配的内存包含了合理的值,这纯粹是运气使然
我要求一些空向量的内存
不,您只需分配内存并将其解释为一个向量。向量为空(甚至可以工作)只是幸运,如上所述。碰巧向量在调用构造函数后会以相同的状态结束
但是,我在向量中添加了一些东西,所以obj2占用的内存增加了,不是吗
不,它不是。任何对象的大小在编译时都是已知的和固定的。一个std::vector
只管理堆内存,例如动态分配的内存。因此它不会增加它自己的大小,也不会增加包含它的结构的大小,而只是增加它所管理的内存的大小
这仍然是一件好事吗
不,绝对不是。如果您需要动态内存,请使用容器、智能指针或至少是new
Oops,创建动态对象和使用malloc分配其内存之间有很大的区别:对象的构造
在您的代码中,永远不会构造test
对象,因此,向量也不是:您的代码使用未初始化的对象调用未定义的行为
如果您被迫使用C模块提供的内存区域,则应考虑使用新的放置方式来完全构造对象:
test* obj2;
obj2 = (test*) malloc(sizeof(test)); // obj2 points to uninitialized memory
obj2 = new((void *) obj2) test; // construct an object in the allocated memory
// including its subobjects (here the vector member)
obj2->tab.push_back(1); // no longer UB...
面向对象,创建动态对象和使用malloc分配其内存之间有很大区别:对象的构造
在您的代码中,永远不会构造test
对象,因此,向量也不是:您的代码使用未初始化的对象调用未定义的行为
如果您被迫使用C模块提供的内存区域,则应考虑使用新的放置方式来完全构造对象:
test* obj2;
obj2 = (test*) malloc(sizeof(test)); // obj2 points to uninitialized memory
obj2 = new((void *) obj2) test; // construct an object in the allocated memory
// including its subobjects (here the vector member)
obj2->tab.push_back(1); // no longer UB...
不要在C++中使用<代码> MalOC/,使用<代码>新< /COD>。当你使用<代码> MalOC/<代码>时,你会要求一些内存中不包含任何东西,并且试图使用一个不存在的对象有未定义的行为。我忘了说为什么我使用Maloc,我现在就改变它。