[英]C++ Void double pointer interference with another
我正在嘗試做一個涉及重載 new 和 delete 的項目。 我在雙空指針中存儲了一個空指針數組(指向分配的隨機內存的指針)。 當然,這個數組需要調整大小以考慮進來的更多空指針。
這是數組的初始化,allocArraySize(int) 設置為 4。
void** allocArray = (void**) calloc ( allocArraySize, sizeof(void*) );
將所有值設置為 nullptr..
for(int i=0; i<allocArraySize; i++){ *(allocArray + i*sizeof(void*)) = nullptr; }
但是,當嘗試調整數組大小時,我注意到當我創建一個新的臨時數組(temp)來存儲它們時,我的原始空指針數組被修改了。
// PRINTS THE ORIGINAL ARRAY
for(int i=0; i<allocArraySize; i++){std::cout<<i<<" = "<<*( allocArray + i*sizeof(void*))<<"\n";}
void** tempArray = (void**)calloc(allocArraySize, sizeof(void*));
// PRINTS THE ORIGINAL ARRAY
for(int i=0; i<allocArraySize; i++){std::cout<<i<<" = "<<*( allocArray + i*sizeof(void*))<<"\n";}`
請注意,我什至還沒有將數組值放入臨時數組中,我仍然遇到這個問題。 這是為什么? 為什么這個隨機值在它確實被初始化時被分配給這個點? 這個新的臨時數組變量如何與我的數組混淆?
注意:這基本上是完整的代碼。 唯一缺少的是主函數、iostream 和 allocArraySize 的聲明。 是的,我知道我並沒有釋放這些可憐的雙指針。 我只是想用最簡單的方式來制造問題。
您正在錯誤地索引指針i * sizeof(void*)
而不是i
。
for(int i=0; i<allocArraySize; i++){ allocArray[i] = nullptr; }
sizeof 乘數不應該存在:
*(allocArray + i*sizeof(void*))
// ^^^^^^^^^^^^^^ this shouldn't be here
void**
是強類型的。 它通過指針算法參與適當的偏移計算。 這里不需要 sizeof 偏移量計算。 該循環似乎是為了轉儲序列中的指針值而設計的,因此應該是:
for(int i=0; i<allocArraySize; i++)
{
std::cout<< i << " = " << allocArray[i] << "\n";
}
首先,您不應該在 C++ 代碼中使用 calloc。 特別是如果您的程序同時使用 new 表達式和 calloc\\malloc,則可能由於不匹配的刪除器而導致 UB。
allocArraySize
類型為void**
,因此它是指向指針的指針。 表達式*allocArraySize
結果與void*
或uintptr_t
類型的 sizeof 相同。 帶指針的算術自動按指向相同類型的下一個對象所需的數量增加指針。
C++ 編寫它的方法甚至不需要這種神秘的知識,您應該做的就是使用一個新表達式並使用空列表對其進行列表初始化,以獲得與 C 中的calloc
相同的效果。
void** allocArray = ::new void*[allocArraySize] {};
for(int i = 0; i < allocArraySize; ++i)
{
std::cout<< i << " = " << allocArray[i] << "\n";
}
從重載的內部使用 new/delete 時,必須使用::
否則會導致無限遞歸。
allocArray[i]
等價於*(allocArray + i)
重載新\\刪除放在一邊。 但真正做到這一點的 C++ 方法是避免裸指針並盡可能使用容器。 New\\delete 可能是一些內存池類使用的包裝器。
// do we really need a vector of pointers?
auto allocArray = std::vector<void*>(allocArraySize, nullptr);
int i = 0;
for( auto &v : allocArray )
std::cout<< (i++) << " = " << v << "\n";
在 C++20 中,由於 init 語句,基於范圍的 for 循環變得更加包含
for(int i = 0; auto &v : allocArray )
std::cout<< (i++) << " = " << v << "\n";
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.