[英]resize an array of pointers without memory leak
我有一個指向對象的指針數組的指針,並且需要調整數組的大小。 我確實意識到這是使用向量的絕好時機,但是我不允許這樣做。 我的代碼可以工作,但是我不完全遵循我寫的內容,並且擔心我可能造成了內存泄漏:
void foo (DataSet &add_data)
{
if (sets == NULL)
{
sets = new DataSet*[1];
sets[0] = &add_data;
}
else
{
DataSet **transfer;
transfer = new DataSet*[num_of_sets];
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
transfer[i] = sets[i];
delete [] sets; // Free the array.
sets = new DataSet*[num_of_sets + 1]; // Create new sets
for (int i = 0; i < num_of_sets; i++) // Copy back
sets[i] = transfer[i];
sets[num_of_sets] = &add_data; // Add the new set
delete [] transfer;
transfer = NULL;
}
num_of_sets++;
}
為什么Visual Studio為以下情況引發異常:
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
*transfer[i] = *sets[i];
但不是:
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
transfer[i] = sets[i];
但是,這兩個代碼段都可以在linux中編譯並正常運行。 此代碼應復制指向對象的指針。 那是怎么回事:
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
transfer[i] = sets[i];
我是否需要擔心以后是否要使用移除功能釋放這些對象?
*transfer[i] = *sets[i];
不像其他示例(不帶星號)那樣復制地址,它嘗試取消引用在這些地址上的DataSet
對象上transfer
和call operator=
的未初始化指針元素。
這是不確定的行為,這就是為什么它在變化的環境下似乎可以工作的原因。
您不需要分配兩次,只需分配一次最終大小即可:
transfer = new DataSet*[num_of_sets + 1]; // Create new sets - final size
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
transfer[i] = sets[i];
delete [] sets; // Free the array.
sets = transfer;
sets[num_of_sets] = &add_data; // Add the new set
// now no need to delete[] transfer
這樣,您還將獲得更好的異常安全性。 -在原始代碼中,您在分配新數據之前刪除了sets
-如果這將引發std::bad_alloc
,則不僅您的對象將變得不一致(具有懸掛的sets
ptr,因為在刪除后您不為其分配null ),但分配給transfer
的內存也會泄漏。 如果您在delete[] sets
之前直接將transfer
分配為最終大小,則如果拋出該異常,則sets
將保持不變,並且transfer
不會泄漏(因為它在分配過程中被拋出,即未分配)。
當然,請確保您在析構函數中delete[] sets
(如果您的指針是指針的所有者,那么還可以包括它們)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.