C++中对象的动态内存分配

Dynamic memory allocation of objects in C++

本文关键字:内存 分配 动态 对象 C++      更新时间:2023-10-16

我正在尝试为非常简单的C++程序中的对象动态分配内存(它不像现在这样动态,但最终会是(。我刚开始上课,最近才开始玩C++,把C抛在了后面。这是代码:

#include <iostream>
using namespace std;
class Test {
  private:
    int i;
  public:
    Test(int);
    ~Test();
    void print();
};
Test::Test(int ii) { i = ii; }
Test::~Test() { i=0; cout << "deconstructor called...value of i= " << i << endl; }
void Test::print() { cout << "value of i= " << i << endl; }
int main()
{
  Test a(10),*b,*c;
  //a.print(); // this works
  b = new Test(12);
  //b->print(); // this works as well
  for (int i=0; i<2; i++)
    c = new Test(i);
  c->print(); /* this shows that the value of i=1 .. should be 0? */
  c[0].print(); /* as expected (I guess), this prints i=1 as well... [expected because c->print() shows i=1 also */
  c[1].print(); /* shows value of i=0... */
  //delete []c; /* this fails miserably, but `delete c` works, why :( */
}

我的很多困惑实际上都包含在代码本身的注释中。我基本上是在尝试一个数组c,其中数组的每个元素都是自己的对象。

注释中描述了我得到的代码的行为。

也许我们应该看看声明,扩展到

Test a(10);
Test *b;
Test *c;

您已经将b和c定义为指向Test的指针,但您似乎希望c是指向Test的一个指针数组。你想要的c的声明很可能是:

Test **c;

您将初始化的:

c = new Test*[2];
for (int i=0; i<2; i++)
   c[i] = new Test(i);

以及您将访问的内容:

c[0]->print();
c[1]->print();

给定的代码很少有严重问题。

  1. *b上执行new,但错过了delete
  2. 您在for循环中多次覆盖*c,这将导致泄漏记忆力在从中分配新资源之前,始终解除分配资源指针
  3. 如果使用new/new[]/malloc进行分配,则必须分别用CCD_ 7解除分配指针。这个和*c一样(这就是它失败的原因(

此外,除了学习动态分配外,还应该了解STL容器,它提供了处理动态资源的更好方法。例如std::vector。

for (int i=0; i<2; i++)
    c = new Test(i);

上面的代码泄漏了内存。c恰好指向循环迭代中最后构造的对象。

c->print((;/*这表明i的值为1。。应该是0?

这里CCD_ 10指向在CCD_ 11上构建的位置。所以,输出。

每个新的[]都应伴随删除[]新建的并伴随delete。两者不能混用。

delete[]不工作是完全正常的:您从未将c分配为数组,而是分配为指针。您可以将数组的地址存储在指针中,但仅此而已。实际上,我想知道c[1]为什么能工作,因为for循环只是在同一个指针中重复存储指向新分配对象的指针(您不是在填充数组!(。

delete c[];仅删除起始元素。如果您想删除该数组,请在循环中使用dz delete c[]

您未能为c分配内存,并继续对其进行错误的编码。如果不将内存分配给指针变量,您如何获得输出?

根据我的说法,你已经多次为*c分配内存作为

for (int i=0; i<2; i++)
c = new Test(i);

看看这个代码,它会让一切都清楚

for (int i=0; i<2; i++)
{   c = new Test(i);    }       /*see , here the loop goes for i=0; then
                                for i=1; which basically overwrites what c will have
                                 i.e. finally       c = new test(1); */
c->print(); /* works fine , gives value of i=1 */
c[0].print(); /* as expected , this prints i=1 as well... */
c[1].print(); /*clearly, it will give a garbage value */
delete c;

但据我说,更换会更好

for (int i=0; i<2; i++)
{   c = new Test(i);    }

带有

c = new Test(1);    //as the previous code is doing the same in for loop but that was consuming more resources

所以,如果你想输出为i=0,然后i=1,那么就这样做-

c = new int(0);
c->print(); /* works fine , gives value of i=0 */
c[0].print(); /* as expected , this prints i=0 as well... */
delete c;
c = new int(1);
c->print(); /* works fine , gives value of i=1 */
c[0].print(); /* as expected , this prints i=1 as well... */
delete c;

以上代码将完全满足您的需求。