我尝试这样做:
#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]<<" ";
}
}
我工作,但是我不明白为什么。当我分配obj2时,我要求一些带有空向量的内存。但是然后,我在该向量中添加了一些东西,所以obj2占用的内存增加了,不是吗?我想知道它为什么起作用,即使它起作用,仍然是一件好事吗?
编辑:这是一个例子。我在由malloc分配的结构中添加了一个向量,因为它以前是用C编写的,因此我无法更改所有分配。我只是将文件传递给了cpp文件。
有效
不,不是。未定义的行为似乎起作用。
但我不明白为什么
为了理解为什么(似乎)起作用,我们必须看一下std::vector
的结构。一个实现可以使用3个指针:
现在您通过malloc()
分配了多个字节,并使用这3个指针将它们解释为一个类。如果我们假设一个指针为4字节大,则您分配12个字节,并将前4个字节解释为指向已分配内存起始位置的指针,将后4个字节解释为已使用内存末尾的指针,并将最后4个字节解释为指针到分配的内存末尾。
此可能工作。但这确实是不确定的行为。例如,对于c ++,它恰好包含全零,这导致所有三个指针均为nullptr
,这很可能也是构造函数要做的。
但是在Visual Studio中,内存not初始化为零,这导致所有三个指针的值都是随机的,这会导致段错误。
所以,为什么这个(似乎)起作用?因为您分配的内存纯属幸运,所以包含合理的值。
我要求一些带有空向量的内存
不,您只是分配内存并将其作为向量。如上所述,向量为空(甚至起作用)只是运气。碰巧向量以与调用构造函数后相同的状态结束。但是然后,我在该向量中添加了一些东西,所以obj2占用的内存增加了,不是吗?
不,不是。任何对象的大小都是已知的,并在编译时固定。 std::vector
仅管理堆内存,例如动态分配的内存。因此,它不会增加自己的大小,也不会增加包含它的结构的大小,而只会增加它管理的内存大小。
这仍然是一件好事吗?不,绝对不是。如果需要动态内存,请使用容器,智能指针或至少使用
new
。