簡體   English   中英

為什么我不能通過指針從數組中刪除第一個元素

[英]Why can't I delete other-than-first element from array by pointer

考慮以下代碼:

int main()
{
  int *intArPtr = new int[100];
  int *intArPtr1 = intArPtr + 1;

  delete [] intArPtr; //ok
  //delete intArPtr; //valgrind warning, but no leaks!
  //delete intArPtr1; //invalid pointer error

  return 0;
}

我知道delete [] intArPtr是刪除這個數組的唯一有效方法,但我只是對以下內容感到好奇:

  1. 為什么delete intArPtr不會產生任何內存泄漏? 是不確定的行為,我很幸運沒有任何?
  2. 為什么delete intArPtr1會在運行時出錯? 為什么不首先從數組中刪除所有元素?
  3. C ++的運行時如何知道已分配數組的大小(對於delete [])? 它存放在某個地方嗎?
  1. 為什么delete intArPtr不會產生任何內存泄漏? 是不確定的行為,我很幸運沒有任何?

正確,在使用new[]分配的內存上調用delete是未定義的行為。 首先,它不會調用數組成員上的析構函數。

對於兩個,即使您只是詢問內存釋放而不是關於對象破壞, deletedelete[]也可以相同地實現,或者它們可以不同。 他們讀起來就像他們是一樣的但他們不是: deletedelete[]是兩個不同的運算符,可能有不同的實現。 他們可以使用不同的分配策略(參見下面問題#3的答案)。

  1. 為什么delete intArPtr1會在運行時出錯? 為什么不首先從數組中刪除所有元素?

你必須傳遞delete一個用new分配的指針。 確切的指針。 不是new分配的內存區域中的指針,不起作用。 它必須是指向該區域起點的相同指針。

  1. C ++的運行時如何知道已分配數組的大小(對於delete [])? 它存放在某個地方嗎?

公共分配器策略是存儲在分配區域之前分配的字節數。 然后delete將獲取您傳遞它的指針,向左看4或8個字節,並將該整數解釋為該區域的大小。 如果您將指針傳遞給其他地方,則其回溯策略將失敗。

C ++語言沒有指定如何跟蹤內存分配,因此這是一個實現細節。 不同的標准庫,編譯器和操作系統將以不同方式執行此操作。 我所描述的只是一種可能的機制。

進一步閱讀:

  1. 為什么刪除intArPtr不會產生任何內存泄漏? 是不確定的行為,我很幸運沒有任何?

是的,不是在同一時間。 使用delete而不是delete[]並不干凈,但通常有效。 基本上,指針和偏移量都在分配時存儲。 這允許在使用delete時進行適當的釋放,即使是偶然的。

  1. 為什么刪除intArPtr1會在運行時出錯? 為什么不首先從數組中刪除所有元素?

intArPtr1與分配區域的指針不對應。 嘗試delete ,運行時無法在分配表中找到此地址。

  1. C ++的運行時如何知道已分配數組的大小(對於delete [])? 它存放在某個地方嗎?

它存儲在分配表中,指針指向已分配的區域。

回答:

  1. 你的例子沒有內存泄漏。 事實上,如果數組中的對象有自己分配的內存並且應該在析構函數中釋放該內存,則刪除不帶[]的數組只會導致內存泄漏。 在所有其他情況下,不正確的刪除不會導致內存泄漏。
  2. 因為分配的內存大小就存儲在指針之前。 當你訪問數組的任何其他元素但第一個時,那里沒有適當的內存大小。
  3. 見2。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM