5

我正在尝试为一个非常简单的 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,其中数组的每个元素都是它自己的对象。

我得到的代码的行为在评论中描述。

4

6 回答 6

5

给定的代码几乎没有严重的问题。

  1. 继续表演new*b但错过了delete
  2. 您在循环中覆盖*c了几次,这会泄漏内存。for始终在从指针分配新资源之前释放资源。
  3. 如果您正在分配,new/new[]/malloc那么您必须delete/delete[]/free分别解除分配指针。您没有维护的相同*c(这就是它失败的原因)。

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

于 2011-07-25T03:30:56.363 回答
5

也许我们应该看看声明,扩展你有:

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

您已将 b 和 c 定义为指向测试的指针,但您似乎希望 c 成为测试指针的数组。您想要的 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();
于 2011-07-25T03:34:03.800 回答
0
for (int i=0; i<2; i++)
    c = new Test(i);

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

c->打印();/* 这表明 i=1 .. 的值应该是 0?

这里c指向构建在 上的位置new Test(1);。所以,输出。

每一个new[]都应该伴随着delete[]new伴随着delete。您不能将两者混合使用。

于 2011-07-25T03:27:40.173 回答
0

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

于 2011-07-25T03:34:31.537 回答
0

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

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

于 2013-09-22T13:47:09.287 回答
0

根据我的说法,您已多次为 *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;

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

于 2018-06-05T18:16:47.710 回答