[英]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;
歸結為? 復制一個指針 ,這意味着**values
和a->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創建的內容,但是如果TC
的destructor
嘗試刪除數組(盡管對於同一對象不應多次調用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]
這將執行以下操作:
4th
(用於索引從0開始計數的值)數組元素的值, see 5
加載see 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.