处理c ++中的指针数组并删除它们

时间:2013-05-28 19:32:10

标签: c++ arrays pointers

我创建了一个测试类(tc),它包含一个指向int的数组指针。

class TC
{
public:
    int **values;
    TC(){values = new int*[10];
 };

当我实例化实例并进行以下更改时:

TC *a = new TC();    
int **values = &*a->values;
int **oldvalues = values;
values = new int*[10];
values[0] = oldvalues[0];
...
values[9] = oldvalues[9];

delete [] oldvalues;

for(int i = 0; i < 10; i++){
    delete values[i];
}

delete [] values;

现在有趣的是:

values = new int*[10];
*a->values = *values;

values[0] = new int(1);
values[9] = new int(10);
std::cout << *values[0] << " " << *values[9];

打印出来

1 10

但切换两行

values = new int*[10];
*a->values = *values;

*a->values = *new int*[10];    
values = &*a->values;

打印

182939382 10

第一部分是指针。

有人可以解释为什么会这样吗?两种处理指针的方法有什么区别?

编辑: 我很欣赏建设性的意见。您可能会告诉我没有任何c ++和指针处理经验。所以请帮助我理解我所犯的错误。

2 个答案:

答案 0 :(得分:4)

*a->values = *values;

相同
 a->values[0] = values[0];

但是values[0]未初始化,所以你不想从中读取。

答案 1 :(得分:1)

如果这很长,您可以跳到底部的 tldr 部分,但这不会帮助您理解问题,因此您需要阅读其余部分。


我的生锈,但有一些非常奇怪的部分:

让我们从这开始:

TC *a = new TC();    
int **values = &*a->values;
int **oldvalues = values;
values = new int*[10];
values[0] = oldvalues[0];
...
values[9] = oldvalues[9];

delete [] oldvalues;

for(int i = 0; i < 10; i++){
    delete values[i];
}

delete [] values;

TC *a = new TC();    

非常好

int **values = &*a->values;

让我们一步一步地看看下半部&*a->values;

  a              //pointer to tc
  a->values      //access values member of the tc a points to
                 //this is a int**
 *a->values      //dereference the int**, so we have a int*  
&*a->values;     //get the address of int*, so we have int** again

总之,正如评论中所述,你可以写a->values. 让我们看一下,你似乎使用int **来保存指向int指针数组的指针。

现在int **values = a->values;归结为什么?你复制一个指针,这意味着**valuesa->values现在引用相同的地址(稍微关闭,但现在考虑将Arrays作为指向第一个元素的指针,必须使用索引运算符[],否则它们引用第一个元素)。这意味着您指向两次相同的数组

值            \            | - 由TC()创建的数组{values = new int * [10];            / a-&gt; values /

int **oldvalues = values;

基本上你创建了一个指向同一个数组的第三个指针,原因是什么?

values = new int*[10];

在您将 values初始化为a->values之前从 values[0] = oldvalues[0]; ... values[9] = oldvalues[9]; 读取一次之前覆盖 delete [] oldvalues;

oldvalues

注意到你有两个指针,你现在复制数据。复制内存块的循环或函数可以简化这一点,但我建议使用stl类,从stl中查看vector

TC

删除TC,删除destructor - 类使用的数组。 虽然需要删除使用new创建的内容,但如果delete的{​​{1}}尝试删除数组(尽管不应多次调用values),这可能会很糟糕。同一个对象)。此外,由于您的班级似乎认为for(int i = 0; i < 10; i++){ delete values[i]; } delete [] values; 是有效的,为什么不覆盖数组中的值?

*arrayOfPointers[3]

你记得在删除数组之前删除所有整数,这很好,但为什么不覆盖它们呢?此外,如果你写一个(你应该),这也应该由析构函数处理。对于可疑的东西,为什么要复制元素,只是为了删除它们?

此外,为什么不使用整数数组呢?是一个真正需要的整数指针数组吗?

这将是一个int数组[1,2,3,7]。 虽然这是一个指针数组:[见1,见2,见4,见5],此外你在以下内存地址中有以下数字1 @ 1,2 @ 2,3 @ 4,7 @ < / p>

对于指针数组,您必须执行以下操作才能获得数字:

4th

执行以下操作:

  1. see 5的值(用于索引开始计数为0)数组元素,7已加载
  2. 取消引用该值,这意味着计算机在内存位置查找标签为5,并看到aarrayOfIntegers[3]
  3. 对于整数数组values = new int*[10]; 就足够了,可以节省一个间接级别。


    到最后一个片段:

    *a->values = *values;
    

    您创建一个数组来替换刚刚删除的数组。

    a->values = new int*[10];
    

    指定第一个元素,请参阅Ben Voigts answer并记住数组只是指向第一个元素的指针。你取消引用它就可以复制第一个数组元素。您可以将这两行放在一起,并通过放置:

    来消除错误
    values[0] = new int(1);
    values[9] = new int(10);
    std::cout << *values[0] << " " << *values[9];
    

    返回您的代码:

    TC *a = new TC();
    a->values[0] = 1;
    a->values[9] =10:
    std::cout << a->values[0] << " " << a->values[9];
    

    你经历了所有这些麻烦,只是改变了第一个和最后一个号码......


    TLDR,更短的解决方案

    让我告诉你如何以更短的方式完成:

    类TC { 上市:     int *值;     TC():values(new int [10]){} // google初始化列表     ~TC(){删除值; } //析构函数,在需要清理实例时调用  };

    用法:

    TC a();
    a.values[0] = 1;
    a.values[9] =10:
    std::cout << a.values[0] << " " << a.values[9];
    

    或没有指针

    {{1}}