LoginSignup
13
5

More than 5 years have passed since last update.

new[] で作ったポインタを基底クラスへのポインタに変換してはいけない

Posted at

まずいコードの例

要するにこういうの

c++
base_t * p = new derived_t[2];
// do something
delete[] p;

は、ダメ。警告出ないけど、ダメ。

念のために周りを書いておくと。
こんな

c++

class base_t
{
  // 略
public:
  base_t(){ /* 略 */  }
  virtual ~base_t(){ /* 略 */  }
};

class derived_t : public base_t
{
  // 略
public:
  derived_t(){ /* 略 */  }
  ~derived_t() override { /* 略 */  }
};

感じ。

なぜダメなのか

new derived_t[2] で作られるメモリは、派生クラスの配列(のようなもの)。得られるポインタはその先頭。

例えば

c++
char * addr = reinterpret_cast<char*>( new derived_t[2] );

とすると、ふたつ目の derived_t。は、addr+sizeof(derived_t) から始まる。
ここで派生クラスのサイズが必要になる。

これを

c++
base_t * p = new derived_t[2];

と、基底クラスに変換してしまうと、p[1]addr+sizeof(base_t) を指すことになり、不幸になる。

delete[] で死ぬ。

13
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
5