在循环中初始化预分配的结构体实例
initializing pre-allocated struct instances within a loop
我想使用malloc()为特定结构的特定数量的实例分配内存。然后,我想在循环中初始化每个实例。但是,对于每次迭代,我观察到构造函数和之后的析构函数都被调用……为什么?更让我惊讶的是,尽管调用了析构函数,但我的每个实例都在循环之后存在……我的实例初始化为相同的值!我肯定错过了一些重要的东西……如果有人能帮助我,我会很感激,因为现在,我无法解释发生了什么。下面是我的c++代码:
struct myStruct{
int* a;
int* b;
myStruct(int x, int y)
{
std::cout << "the constructor is called" << std::endl;
a = (int*)malloc(x*sizeof(int));
b = (int*)malloc(y*sizeof(float));
}
~myStruct()
{
std::cout << "the destructor is called" << std::endl;
delete[] a;
delete[] b;
} };
int main(int argc, char** argv){
int Nb = 3;
myStruct *S = (myStruct*)malloc(Nb*sizeof(myStruct));
for(int i=0 ; i<Nb ; i++)
{
*(S+i) = myStruct(1,2);
}
std::cout << std::endl;
for(int i=0 ; i<Nb ; i++)
{
std::cout << "instance " << i << " :" << std::endl;
std::cout << (unsigned int)(*(S+i)->a) << std::endl;
std::cout << (unsigned int)(*(S+i)->b) << std::endl << std::endl;
}
system("PAUSE");}
命令窗口显示:
构造函数被称为
析构函数被称为构造函数被称为
析构函数被称为构造函数被称为
析构函数被称为实例0:16085247124277075694
实例1:16085247124277075694
实例2:16085247124277075694
按任意键继续…
在表达式
*(S+i) = myStruct(1,2)
所发生的是,您创建了一个临时实例的结构(myStruct(1,2)
部分),然后复制该实例到S[i]
。复制是浅层的,因此只复制指针,不分配或复制新数据。表达式完成后,临时实例就不再需要了,因此它被销毁了。
这种销毁当然会导致释放数据成员,因此数组(副本)结构体中的指针不再有效,访问它们是未定义的行为。而且,你实际上并没有将分配的内存初始化为任何东西,因此内存将包含分配之前在那里的任何内容,并且内容看起来是随机的。
我建议你读一下std::vector
, std::shared_ptr
,最重要的是三法则。
每次通过循环,代码都会创建一个临时对象(myStruct(1,2)
),然后销毁它。这就是输出显示的内容。
这个临时对象被赋值给未初始化的对象*(S+i)
,这不是一件好事。对象应该由构造函数初始化,而不是赋值操作符。这里使用构造函数的方法是放置new:
new (S+i) myStruct(1,2);
括号内的第一个值是要构造对象的地址。
这样做之后,正如其他人提到的,您不能在结果数组上使用delete
,因为它不是用new
创建的。因此,您必须循环遍历对象并显式地调用每个对象的析构函数,然后free
内存。
- 根据用户回答声明"Players"。用户选择玩家数量。播放器是结构体
- 结构体 S { int align; } 之间的区别;(struct 关键字后的名称)和 struct { int al
- C++ - 如何在结构向量中找到结构体一个成员的最大值?
- 包含 std::list 的结构体的 C++ 初始化
- 结构体和类的不同大小(),彼此具有相同的字段类型
- 如何使用结构体的向量数组?
- 如何使用结构体在C++中更改这些代码?
- 无法在 Mosquitto MQTT Broker 插件上访问结构体 mosquitto 的元素
- 我应该如何在C++中使用结构体解决输入失败的问题?
- Qsort() 比较结构体整数的总和
- 如何使用迭代器指向结构体c++的向量
- 在C++中使用链表的堆栈实现中,访问结构体headNode成员count和top会导致运行时错误
- 如何获取结构体成员的地址
- 如何创建一个公共python函数,它可以接收c++结构体/实例或python对象作为参数
- 用包含const成员的结构体实例替换堆栈与静态变量
- 用结构体的所有实例调用函数
- 在循环中初始化预分配的结构体实例
- 为什么使用带可变模板参数的结构体同时实例化两个模板
- c++模板:我可以/如何使用结构体作为模板的实例化类型
- 结构体需要访问类的私有实例变量