0

I want to allocate memory for a certain number of instances of a certain structure, using malloc(). Then, i want to initialize each instance within a loop. But, for each iteration, i observ that the constructor, and the destructor just after, are called... why? More suprising for me is the fact that each of my instance exists after the loop despite of the call of the destructor... and my instances are initialized with same values! I'm definitively missing something important... I would be grateful if someone can help me because for now, i can't explain what happen. Here is my C++ code :

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");}

My command window display :

the constructor is called

the destructor is called

the constructor is called

the destructor is called

the constructor is called

the destructor is called

instance 0 : 1608524712 4277075694

instance 1 : 1608524712 4277075694

instance 2 : 1608524712 4277075694

Press any key to continue . . .

Best Regards

4

2 回答 2

0

每次通过循环,代码都会创建一个临时对象 ( myStruct(1,2)),然后将其销毁。这就是输出显示的内容。

该临时对象被分配给未初始化的对象*(S+i),这不是一件好事。对象应该由构造函数初始化,而不是赋值运算符。这里使用构造函数的方式是placement new:

new (S+i) myStruct(1,2);

括号中的第一个值是构造对象的地址。

这样做后,正如其他人所提到的,您不能delete在结果数组上使用,因为它不是用new. 因此,您必须遍历对象并显式调用每个对象的析构函数,然后调用free内存。

于 2013-05-02T11:57:46.287 回答
0

在表达式中

*(S+i) = myStruct(1,2)

发生的事情是您创建结构(零件)的临时实例,然后将该实例复制到. 复制是浅的,所以只有指针被复制,没有新的数据被分配或复制。表达式完成后,不再需要临时实例,因此它被破坏了。myStruct(1,2)S[i]

这种破坏当然会导致数据成员的释放,因此数组(副本)中结构中的指针不再有效,访问它们是未定义的行为。此外,您实际上并未将分配的内存初始化为任何内容,因此内存将包含分配之前的任何内容,并且内容看起来是随机的。

我建议你阅读关于std::vector,std::shared_ptr最重要的是关于三法则

于 2013-05-02T11:55:53.687 回答