C++ 在循环中初始化预分配的结构实例
我想使用malloc()为特定结构的特定数量的实例分配内存。 然后,我想初始化循环中的每个实例。 但是,对于每一次迭代,我观察到构造函数和之后的析构函数都被调用。。。为什么? 更让我惊讶的是,尽管调用了析构函数,我的每个实例都存在于循环之后。。。并且我的实例是用相同的值初始化的! 我肯定错过了一些重要的事情。。。如果有人能帮助我,我将不胜感激,因为目前我无法解释发生了什么。 这是我的C++代码:C++ 在循环中初始化预分配的结构实例,c++,loops,struct,instance,C++,Loops,Struct,Instance,我想使用malloc()为特定结构的特定数量的实例分配内存。 然后,我想初始化循环中的每个实例。 但是,对于每一次迭代,我观察到构造函数和之后的析构函数都被调用。。。为什么? 更让我惊讶的是,尽管调用了析构函数,我的每个实例都存在于循环之后。。。并且我的实例是用相同的值初始化的! 我肯定错过了一些重要的事情。。。如果有人能帮助我,我将不胜感激,因为目前我无法解释发生了什么。 这是我的C++代码: struct myStruct{ int* a; int* b; myStruct
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");}
struct myStruct{
int*a;
int*b;
myStruct(整数x,整数y)
{
表达式中的std::cout
*(S+i) = myStruct(1,2)
所发生的情况是,您创建了一个结构的临时实例(myStruct(1,2)
部分),然后将该实例复制到S[i]
。复制很浅,因此只复制指针,不分配或复制新数据。表达式完成后,不再需要临时实例,因此它被销毁
这种破坏当然会导致释放数据成员,从而释放数组(副本)中结构中的指针不再有效,访问它们是未定义的行为。此外,您实际上不会将分配的内存初始化为任何内容,因此内存将包含分配之前的内容,并且内容看起来是随机的
我建议您阅读,最重要的是。每次通过循环,代码都会创建一个临时对象(myStruct(1,2)
),然后销毁它。这就是输出所显示的内容
该临时对象被分配给未初始化的对象*(S+i)
,这不是一件好事。对象应该由构造函数而不是赋值运算符初始化。此处使用构造函数的方法是:
new (S+i) myStruct(1,2);
括号中的第一个值是要构造对象的地址
这样做之后,正如其他人所提到的,您不能对结果数组使用delete
,因为它不是用new
创建的。因此,您必须循环遍历对象并显式调用每个对象上的析构函数,然后释放内存。您使用malloc
进行分配,但使用d进行释放elete
?那不行。谢谢你的回复,Joachim。事实上,我应该使用“new”而不是malloc。这是我的新构造函数:myStruct(int x,int y){std::cout好的,我理解“三个法则”现在!我必须定义一个显式的复制构造函数,以确保当为我的临时实例调用析构函数时,我实例的数据成员将保持安全。@LorentzLorentz复制构造函数和复制赋值运算符。如果您的编译器足够新,还需要它们的版本。谢谢Pete。好的,使用“new”这个位置,析构函数不再被调用,但实例仍使用与我的命令窗口显示的相同值进行初始化:构造函数被调用构造函数被调用构造函数被调用实例0:3452816845 3452816845实例1:3452816845 3452816845实例2:3452816845 3452816845按任意键继续…抱歉皮特,忘了我的最后一个答案。它现在很有效。谢谢你