c++中指针数组的处理和删除

Handling of arrays of pointers in c++ and deleting them

本文关键字:处理 删除 数组 指针 c++      更新时间:2023-10-16

我创建了一个测试类(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];

打印出

10

1

但是两行互换

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

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

打印

182939382 10

第一部分是某个指针。

谁能解释一下为什么会这样?处理指针的两种方式有什么不同?

编辑:我希望能有建设性的意见。你可能会说我没有任何c++和指针处理的经验。所以请帮助我了解我所犯的错误。

This

*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现在指向相同的地址(稍微偏离,但现在将数组视为指向第一个元素的指针,必须使用索引操作符[]延迟,否则它们指向第一个元素)。这意味着你两次指向同一个数组

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

int **oldvalues = values;

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

values = new int*[10];

这里,在初始化为a->values时,覆盖了 values,然后从它读取一次。

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

注意到你有两个指针,你现在复制数据。循环或函数复制内存块可以缓解这个问题,但我建议使用stl类,从stl.

中查看vector。
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被加载
  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{公众:int *值;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];