2017-04-15 92 views
1

的陣列所以,我有一個類堆損壞當刪除指針

class Room { 
    public: 
     Room(); 
     ~Room(); 
     tile::Tile* tile[11][7]; // Owned 
} 

的有一個構造和析構函數,tile::Tile是一個抽象基類,所以是一個指針。指針數組tile,需要像這樣在構造函數中填充。

Room::Room() { 
    for (std::size_t i = 0; i < 11; ++i) { 
     for (std::size_t j = 0; j < 7; ++j) { 
      this->tile[i][j] = new tile::Empty(); 
     } 
    } 
} 

從我的理解,我也應該在Room的析構函數刪除這些。

Room::~Room() { 
    for (std::size_t i = 0; i < 11; ++i) { 
     for (std::size_t j = 0; j < 7; ++j) { 
      delete this->tile[i][j]; 
     } 
    } 
} 

然而,這樣做導致的0xc0000374返回代碼,這是一個堆損壞錯誤。爲什麼這個腐敗錯誤發生?

最小例如

class Tile {}; 

class Empty: public Tile { 
    public: 
     Empty() {} 
}; 

class Room { 
    public: 
     Tile* tiles[5]; 
     Room() { 
      for (int i = 0; i < 5; ++i) { 
       tiles[i] = new Empty(); 
      } 
     } 
     ~Room() { 
      for (int i = 0; i < 5; ++i) { 
       delete tiles[i]; 
      } 
     } 
}; 

class Maze { 
    public: 
     Room rooms[5]; 
     Maze() { 
      for (int i = 0; i < 5; ++i) { 
       rooms[i] = Room(); 
      } 
     } 
}; 

int main() { 
    Maze maze = Maze(); 
} 
+1

你已經損壞了創建和銷燬之間的堆。猜測你做了什麼或做什麼是不可能的。 – molbdnilo

+0

什麼是'tile :: Empty()'? – SomeWittyUsername

+1

由於@molbdnilo說錯誤在別處。將上面的代碼轉換成[mcve]並查看它是否仍然發生。 –

回答

0

如果這是所有的代碼,那麼它看起來OK。 我假設你有更多的代碼在析構函數之前刪除了其中的一些條目。

無論如何您必須在刪除之後立即爲指針分配NULL,因此對delete的其他調用不會引發異常。

如果有其他代碼在析構函數之前調用delete,並且沒有將指針指定爲NULL,那麼這將解釋異常。

0

好的,所以我的代碼的問題實際上是在Room對象的構造中。我有一個循環初始化一個5乘5的數組和默認構造函數(即rooms[i][j] = Room())。刪除它(因爲C++會自動使用數組的默認構造函數)解決了這個問題!

class Tile {}; 

class Empty: public Tile { 
    public: 
     Empty() {} 
}; 

class Room { 
    public: 
     Tile* tiles[5]; 
     Room() { 
      for (int i = 0; i < 5; ++i) { 
       tiles[i] = new Empty(); 
      } 
     } 
     ~Room() { 
      for (int i = 0; i < 5; ++i) { 
       delete tiles[i]; 
      } 
     } 
}; 

class Maze { 
    public: 
     Room rooms[5]; 
     Maze() { 
      //for (int i = 0; i < 5; ++i) { 
      // rooms[i] = Room(); 
      //} 
     } 
}; 

int main() { 
    Maze maze = Maze(); 
} 
+0

你的代碼還有問題。如果您的程序中使用了copy ctor,您將結束雙重刪除Tile *。谷歌爲「三的統治」。 –

+0

在我的真實代碼庫中,tile有一個虛擬析構函數 –

+0

這不會改變問題。如果你的程序以某種方式使用默認生成的拷貝文件,那麼這兩個實例(舊的和複製的)將共享相同的磁貼指針,並且都會調用它們的刪除。這可能會造成內存損壞的情況,在任何不同的上下文中都會出現錯誤 –