繁体   English   中英

在C ++中处理指针数组并删除它们

[英]Handling of arrays of pointers in c++ and deleting them

我创建了一个测试类(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 ++和指针处理没有任何经验。 因此,请帮助我了解我所犯的错误。

这个

*a->values = *values;

是相同的

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

但是values[0]尚未初始化,因此您不想从中读取值。

如果这很想让您跳到底部的tldr部分,但这并不能帮助您理解问题,因此您需要阅读其余部分。


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

让我们以此开始:

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视为指向第一个元素的指针,必须将其与索引运算符[] ,否则它们引用第一个元素)。 这意味着您两次指向同一阵列

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

int **oldvalues = values;

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

values = new int*[10];

在这里,在将values初始化为a->values之前,您将覆盖 values然后再读取一次。

values[0] = oldvalues[0];
...
values[9] = oldvalues[9];

注意,现在有两个指针可以复制数据。 循环或复制内存块的函数可以减轻这种情况,但是我建议使用stl类,从stl中检出向量

delete [] oldvalues;

您将删除oldvalues ,这将删除TC -Class使用的数组。 尽管需要删除使用new创建的内容,但是如果TCdestructor尝试删除数组(尽管对于同一对象不应多次调用delete ,这可能会很麻烦。 此外,由于您的类似乎假设values始终有效,因此为什么不覆盖数组中的值?

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

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

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

这将是一个int数组[1、2、3、7]。 虽然这是一个指针数组:[请参见1,请参见2,请参见4,请参见5],此外,在以下存储器地址1 @ 1、2 @ 2、3 @ 4、7 @ 5处还有以下数字

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

*arrayOfPointers[3]

这将执行以下操作:

  1. 4th (用于索引从0开始计数的值)数组元素的值, see 5加载see 5
  2. 该值已取消引用,这意味着计算机在带有标签5的内存位置中查找并看到7

对于整数数组, aarrayOfIntegers[3]足以节省一个间接级别。


到最后一个片段:

values = new int*[10];

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

*a->values = *values;

您分配了第一个元素,请参见Ben Voigts的答案,并记住数组只是指向第一个元素的指针。 取消引用后,您将复制第一个数组元素。 您可以将这两行合而为一,并通过以下方式消除错误:

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

返回您的代码:

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

您遇到了所有麻烦,只是更改了第一个和最后一个号码。


TLDR,较短的解决方案

让我展示给你看,它可以用更短的方法完成:

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

用法:

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

或没有指针

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM