ページ 11

C++におけるdelete hoge と delete[] hogeの使い分けについて

Posted: 2015年7月05日(日) 18:39
by hage
deleteは配列では無く、単体でnewされた物に対して使用し
delete[]は配列でnewされた物に対して使用しますよね、
この時、単体でnewされた物に対してdelete[]は使ってはいけないのでしょうか?
hoge=new int;もhoge=new int[1];
と同じ意味ですし、delete hogeじゃなくて、delete[] hoge;で統一しちゃったりとかしたらダメなんですかね?

Re: C++におけるdelete hoge と delete[] hogeの使い分けについて

Posted: 2015年7月05日(日) 20:01
by h2so5
ダメです。

Re: C++におけるdelete hoge と delete[] hogeの使い分けについて

Posted: 2015年7月05日(日) 20:16
by hide
C言語のポインタから見なおしたほうがいいかもしれないですよ。

Re: C++におけるdelete hoge と delete[] hogeの使い分けについて

Posted: 2015年7月05日(日) 20:59
by へにっくす
hage さんが書きました:hoge=new int;もhoge=new int[1];
と同じ意味ですし、delete hogeじゃなくて、delete[] hoge;で統一しちゃったりとかしたらダメなんですかね?
そのやり方は言語の規格書に載っていません。よって未定義です。
同じ意味ととらえてしまう貴方には、なぜ型が存在するのかをちゃんと考えてほしいですね。
配列と配列でないのと一緒にする、という話と同じですから。

Re: C++におけるdelete hoge と delete[] hogeの使い分けについて

Posted: 2015年7月05日(日) 21:25
by softya(ソフト屋)
そう言うのが面倒なら、ガベージコレクションのあるJavaやC#を選択されるべきだと思います。
あるいはSTLなどで固めてnewを自分で書かないコーディングを徹底するかですね。

Re: C++におけるdelete hoge と delete[] hogeの使い分けについて

Posted: 2015年7月05日(日) 21:31
by かずま

コード:

#include <iostream>
 
class A {
public:
    A() { std::cout << "constructor\n"; }
    ~A() { std::cout << "desnstructor\n"; }
};

int main()
{
    A *p = new A[3];
    delete p;
}
このプログラムは、VC++ でも g++ でもコンパイルできますが、
実行するとどちらも異常終了します。

new[3] では、コンストラクタを 3つ呼び出します。delete[] では、new[] で
呼び出したのと同じ個数のデストラクタを呼び出さなければなりません。

それが delete だと、デストラクタを 1個しか呼び出しません。
これが delete[] を使わなければならない理由の一つです。

次に、なぜ、プログラムが異常終了するのかを説明します。

delete[] が new[] で確保したインスタンスの個数を知るためには、new[] が
それをどこかに記憶しておかなければなりません。

new[] は、その個数の領域とその個数分のインスタンスの領域を一括して確保し、
確保した領域のアドレスではなく、個数の領域の次のインスタンスの領域の
アドレスを返します。

delete[] は、指定されたアドレスのひとつ前に個数が入っているので、それを
使ってデストラクタをその個数だけ呼び出した後、本当に確保されたアドレスで
すべての領域を解放します。

delete は、指定されたアドレスで解放するので、それは本当に確保された
領域ではないため、異常終了するのです。

Re: C++におけるdelete hoge と delete[] hogeの使い分けについて

Posted: 2015年7月05日(日) 21:41
by hage
deleteとdelete[]ってそんな違いがあったんですね。
有難う御座います。

Re: C++におけるdelete hoge と delete[] hogeの使い分けについて

Posted: 2015年7月05日(日) 21:42
by かずま
ちょっと補足します。

コード:

#include <iostream>
 
class A {
public:
    A() { std::cout << "constructor\n"; }
};
 
int main()
{
    A *p = new A[3];
    delete p;
}
このプログラムは異常終了しません。
デストラクタがないクラスの場合、個数を記憶する必要がないので、
delete も delete[] も指定したアドレスを解放するだけだからです。
その意味では、質問にあった int の場合、delete も delete[] も
問題なく動くので、それで違いが分からず質問されたのだと思います。

Re: C++におけるdelete hoge と delete[] hogeの使い分けについて

Posted: 2015年7月05日(日) 21:50
by hage

コード:

#include <iostream>
 
class A {
public:
    A() { std::cout << "constructor\n"; }
};
 
int main()
{
    A *p = new A;
    delete []p;
}

気になったのはこっちです

Re: C++におけるdelete hoge と delete[] hogeの使い分けについて

Posted: 2015年7月05日(日) 22:14
by たいちう
> 気になったのはこっちです

deleteしなくてはならない配列の要素数が判らなくて困ります。

配列でも配列じゃなくても、常にdelete[](あるいは常にdelete)するような設計も可能だったかもしれませんが、
C++ではそのような文法は採用されませんでした。

# 不採用の理由は、時代的にコンパイラの実装が面倒になるからかな?
# あるいは、プログラマに自由と責任を与えるC言語の方針の踏襲かも。

Re: C++におけるdelete hoge と delete[] hogeの使い分けについて

Posted: 2015年7月06日(月) 00:33
by かずま
hage さんが書きました:気になったのはこっちです
この場合、デストラクタがないので、個数は不要。
delete も delete[] も同じで、p の指す領域をそのまま解放するだけです。