简体   繁体   English

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

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

I have created a test class (tc) which holds an array pointers to int. 我创建了一个测试类(tc),其中包含一个指向int的数组指针。

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

When I instatiate an instance and do the following changes: 当我实例化实例并进行以下更改时:

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;

Now comes the interesting part: 现在来了有趣的部分:

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

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

This prints out 打印出来

1 10 1 10

But switching the two lines 但是切换两条线

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

to

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

prints 版画

182939382 10 182939382 10

Where the first part is some pointer. 第一部分是一些指针。

Can someone explain why this happens? 有人可以解释为什么会这样吗? What makes the difference between the two ways to handle the pointers? 两种处理指针的方式有何不同?

EDIT: I'd appreciate constructive input. 编辑:我将感谢建设性的投入。 As you might be able to tell I don't have any experience with c++ and pointer handling. 如您所知,我对c ++和指针处理没有任何经验。 So please help me understand the errors that I am committing. 因此,请帮助我了解我所犯的错误。

This 这个

*a->values = *values;

is the same as 是相同的

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

But values[0] is uninitialized, so you don't want to be reading from it. 但是values[0]尚未初始化,因此您不想从中读取值。

If this is to long for you skip to the tldr part at the bottom, but that wont help you understand the problems, for that you need to read the rest. 如果这很想让您跳到底部的tldr部分,但这并不能帮助您理解问题,因此您需要阅读其余部分。


my c is rusty but there are some highly strange parts: 我的c生锈了,但是有一些非常奇怪的部分:

lets start with this: 让我们以此开始:

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();    

Perfectly fine 非常好

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

lets look at the second half &*a->values; 让我们看一下下半个&*a->values; , step by step , 一步步

  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

in short as stated in the comments you could just write a->values. 简而言之,如评论中所述,您可以只写a->values. Lets look further, you seem to be using int** to hold a pointer to an array of int pointers. 让我们进一步看一下,您似乎正在使用int **来保存指向int指针数组的指针。

Now what does int **values = a->values; 现在什么是int **values = a->values; come down to? 归结为? You copy a pointer , this means that **values and a->values now refer to the same address (slightly off, but for now consider Arrays as a pointer to the first element, that have to be defered with the index operator [] , otherwise they refer to the first element). 复制一个指针 ,这意味着**valuesa->values现在指向相同的地址(略有偏离,但是现在将Arrays视为指向第一个元素的指针,必须将其与索引运算符[] ,否则它们引用第一个元素)。 This means you point to the same Array twice 这意味着您两次指向同一阵列

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

int **oldvalues = values;

Basically you create a third pointer to the same array, for what reason? 基本上,您出于什么原因创建了指向同一数组的第三个指针?

values = new int*[10];

Here you overwrite values before you read once from it when initializing it to a->values . 在这里,在将values初始化为a->values之前,您将覆盖 values然后再读取一次。

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

noticing that you have two pointers you now copy the data. 注意,现在有两个指针可以复制数据。 A loop or a function to copy chunks of memory could ease this, but I recommend a stl class, check out vector from the stl. 循环或复制内存块的函数可以减轻这种情况,但是我建议使用stl类,从stl中检出向量

delete [] oldvalues;

you delete oldvalues , which is deleting the array that your TC -Class uses. 您将删除oldvalues ,这将删除TC -Class使用的数组。 While one needs to delete what one creates with new, this can be hell, if TC 's destructor tries to delete the array as well (though shall not call delete multiple times for the same object). 尽管需要删除使用new创建的内容,但是如果TCdestructor尝试删除数组(尽管对于同一对象不应多次调用delete ,这可能会很麻烦。 Furthermore since your class seems to assume that values is alwazs valid, why not overwrite the values in the array? 此外,由于您的类似乎假设values始终有效,因此为什么不覆盖数组中的值?

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

you remember to delete all the integers before you delete the array, this is good, but why not overwrite them? 您记得删除数组之前先删除所有整数,这很好,但是为什么不覆盖它们呢? Besides, this should be handled by the destructor as well, if you write one (you SHOULD). 此外,如果您编写了一个(应该),则也应该由析构函数来处理。 BUt what is dubious, why do you copy the elements, just to delete them? 但是什么是可疑的,为什么要复制元素,而只是删除它们?

FUrthermore, why don"t you use an integer array? is an array of pointers to integers really necessary? 此外,为什么不使用整数数组呢?真的需要一个指向整数的指针数组吗?

This would be an int array [1, 2, 3, 7]. 这将是一个int数组[1、2、3、7]。 While this is an array of pointers: [see 1, see 2, see 4, see 5], in addition you have the following numbers at the following memory addresses 1@1, 2@2, 3@4, 7@5 虽然这是一个指针数组:[请参见1,请参见2,请参见4,请参见5],此外,在以下存储器地址1 @ 1、2 @ 2、3 @ 4、7 @ 5处还有以下数字

For the array of pointers you have to do the following to get to a number: 对于指针数组,您必须执行以下操作以获得数字:

*arrayOfPointers[3]

This does the following: 这将执行以下操作:

  1. the value of the 4th (for indexing start counting at 0) array element, see 5 is loaded 4th (用于索引从0开始计数的值)数组元素的值, see 5加载see 5
  2. the value is dereferenced which means the computer looks in the memory location with the label five and sees 7 该值已取消引用,这意味着计算机在带有标签5的内存位置中查找并看到7

For an Array of integers aarrayOfIntegers[3] is sufficient which saves one level of indirection. 对于整数数组, aarrayOfIntegers[3]足以节省一个间接级别。


to the last snippet: 到最后一个片段:

values = new int*[10];

you create an array to replace the one you just deleted. 您创建一个数组来替换刚删除的数组。

*a->values = *values;

you assign the first element, see Ben Voigts answer and remember that an array is just a pointer to the first element. 您分配了第一个元素,请参见Ben Voigts的答案,并记住数组只是指向第一个元素的指针。 SInce you dereference it you copy the first array element. 取消引用后,您将复制第一个数组元素。 You can put these two lines into one and remove the mistake by putting: 您可以将这两行合而为一,并通过以下方式消除错误:

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

Back to your code: 返回您的代码:

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

You went through all this trouble just ot change the first and last number.... 您遇到了所有麻烦,只是更改了第一个和最后一个号码。


TLDR, shorter solution TLDR,较短的解决方案

Let me show you haow it can be done in a shorter way: 让我展示给你看,它可以用更短的方法完成:

class TC { public: int *values; TC类{public:int * values; TC() : values(new int[10]) {} //google initializer list ~TC(){ delete values; TC():values(new int [10]){} // Google初始化程序列表〜TC(){删除值; } //destructor, called when your instance needs to be cleaned up }; } //析构函数,在需要清理实例时调用};

the usage: 用法:

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

or without pointers 或没有指针

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