簡體   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