ページ 11

C++ newによる確保の大きさ.

Posted: 2012年1月19日(木) 18:50
by takumi@0832080.com
[環境]
OS: Windows7 64bit
CPU: intel corei5-2400
メモリ:8GB

C++を始めたばかりですが,以下の内容が調べても分かりません.
分かる方いましたら教えて戴きたいです.

mallocは指定した大きさのメモリ返すと思うのですが,
newはどの程度の大きさのものが返ってくるのですか?
(よく分からないのでC++なのに以下の様にmallocを無理やり使ってます.)

コード:

class Buffer{
	size_t size;
	void *pointer;

	public:

		Buffer(size_t buf){
			size =0;
			pointer = NULL;
			size = buf;
			pointer = malloc(size);
		}
		~Buffer(){
			if(pointer) free(pointer);
		}
		void* Buffer::GetPointer(){
	                           return this->pointer;
                           }
};

Re: C++ newによる確保の大きさ.

Posted: 2012年1月19日(木) 18:59
by beatle
malloc(n) -> nバイト
new T[n] -> sizeof(T) * nバイト
です.
つまり,普通の配列の宣言の様に,確保したい要素数を[n]と書けば,その要素数が丁度入る大きさの領域が確保されます.

Re: C++ newによる確保の大きさ.

Posted: 2012年1月19日(木) 18:59
by softya(ソフト屋)
newは指定された型に必要なメモリが確保されて返されますね。型をsizeofしなくて良い分楽です。
あと大きな違いはnewでクラスのインスタンスを生成するとコンストラクタが呼ばれることです。これは重要です。

Re: C++ newによる確保の大きさ.

Posted: 2012年1月19日(木) 23:22
by takumi@0832080.com
beatle さんが書きました:malloc(n) -> nバイト
new T[n] -> sizeof(T) * nバイト
です.
つまり,普通の配列の宣言の様に,確保したい要素数を[n]と書けば,その要素数が丁度入る大きさの領域が確保されます.
返信有難うございます.例えば 
ClassA *C_a = new ClassA[10] ;
delete(C_a);

ClassA *C_a = (ClassA *) malloc(sizeof(ClassA *)*10) ;
free(C_a);
これは同じ動作ということですね.

Re: C++ newによる確保の大きさ.

Posted: 2012年1月19日(木) 23:24
by takumi@0832080.com
softya(ソフト屋) さんが書きました:newは指定された型に必要なメモリが確保されて返されますね。型をsizeofしなくて良い分楽です。
あと大きな違いはnewでクラスのインスタンスを生成するとコンストラクタが呼ばれることです。これは重要です。

返信有難うございます.ということは基本はnewを使う方が可読性は高いということですね.勉強になりました.

Re: C++ newによる確保の大きさ.

Posted: 2012年1月19日(木) 23:45
by softya(ソフト屋)
takumi@0832080.com さんが書きました:ClassA *C_a = new ClassA[10] ;
delete(C_a);

ClassA *C_a = (ClassA *) malloc(sizeof(ClassA *)*10) ;
free(C_a);
takumi@0832080.com さんが書きました: 返信有難うございます.ということは基本はnewを使う方が可読性は高いということですね.勉強になりました.
まったく違います。
malloc/freeだとコンストラクタ/デストラクタが呼び出されないので支障が出る可能性が高いで基本C++ではmalloc/freeは禁止です。
必ずnew/deleteを使って下さい。さっき書き忘れましたがdeleteならデストラクタが呼び出されます。freeだとメモリが解放されるだけです。

それと
delete[] C_a;
です。配列の時は気を付けましょう。

Re: C++ newによる確保の大きさ.

Posted: 2012年1月20日(金) 00:37
by takumi@0832080.com
softya(ソフト屋) さんが書きました: まったく違います。
malloc/freeだとコンストラクタ/デストラクタが呼び出されないので支障が出る可能性が高いで基本C++ではmalloc/freeは禁止です。
必ずnew/deleteを使って下さい。さっき書き忘れましたがdeleteならデストラクタが呼び出されます。freeだとメモリが解放されるだけです。

それと
delete[] C_a;
です。配列の時は気を付けましょう。
これからは全てnew/deleteを使おうと思います.
malloc/freeとnew/deleteの違いが分かりました.
delete[] C_a;は気をつけます^^;

Re: C++ newによる確保の大きさ.

Posted: 2012年1月20日(金) 07:20
by beatle
なぜ配列にはdelete[]演算子を使うかについて捕捉です.

newにも2種類あります.単体確保用のnewと,配列確保用のnew[]です.
softyaさんが言うように,new, new[]するとコンストラクタが呼び出されます.
new[]を使うと,各要素に対してコンストラクタが呼び出されます.つまり配列の要素数と同じ回数コンストラクタが呼ばれます.
同様に,deleteは単体オブジェクト用のデストラクタ呼び出し,delete[]は配列要素数分のデストラクタ呼び出しをします.

ということで,配列の生成・破棄にはnew[],delete[]を使わないといけません.

Re: C++ newによる確保の大きさ.

Posted: 2012年1月20日(金) 08:51
by たかぎ
処理系にもよるので一概には言えないのですが...

配列に対するnewの場合、要素の型がC互換型でなければ、配列の直前に要素数が挿入される実装が多いようです。
具体的には...

コード:

struct A
{
    ~A();
};

int main()
{
    A* ptr = new A[10];
    delete[] ptr;
}
とした場合、new A[10]で割り付けられるサイズはsizeof(A[10])ではなく、少なくともsizeof(A[10])+sizeof(std::size_t)になるというわけです。
(実際には、要素数はstd::size_t型ではないかもしれませんし、境界調整の関係で詰め物が入る可能性もあります)

ここからもわかるように、deleteとdelete[]では、解放するメモリのサイズも違いますし、デストラクタの呼び出し方も異なります。

Re: C++ newによる確保の大きさ.

Posted: 2012年1月22日(日) 00:06
by takumi@0832080.com
beatle さんが書きました:なぜ配列にはdelete[]演算子を使うかについて捕捉です.

newにも2種類あります.単体確保用のnewと,配列確保用のnew[]です.
softyaさんが言うように,new, new[]するとコンストラクタが呼び出されます.
new[]を使うと,各要素に対してコンストラクタが呼び出されます.つまり配列の要素数と同じ回数コンストラクタが呼ばれます.
同様に,deleteは単体オブジェクト用のデストラクタ呼び出し,delete[]は配列要素数分のデストラクタ呼び出しをします.

ということで,配列の生成・破棄にはnew[],delete[]を使わないといけません.
捕捉有難うございます. 

Re: C++ newによる確保の大きさ.

Posted: 2012年1月22日(日) 00:21
by takumi@0832080.com
たかぎ さんが書きました:処理系にもよるので一概には言えないのですが...

配列に対するnewの場合、要素の型がC互換型でなければ、配列の直前に要素数が挿入される実装が多いようです。
具体的には...

コード:

struct A
{
    ~A();
};

int main()
{
    A* ptr = new A[10];
    delete[] ptr;
}
とした場合、new A[10]で割り付けられるサイズはsizeof(A[10])ではなく、少なくともsizeof(A[10])+sizeof(std::size_t)になるというわけです。
(実際には、要素数はstd::size_t型ではないかもしれませんし、境界調整の関係で詰め物が入る可能性もあります)

ここからもわかるように、deleteとdelete[]では、解放するメモリのサイズも違いますし、デストラクタの呼び出し方も異なります。
今回のお題とは関係無いですが,構造体にコンストラクタ/デストラクタがあったのは知らなかったです.
捕捉有難うございます.

Re: C++ newによる確保の大きさ.

Posted: 2012年1月22日(日) 02:08
by たかぎ
takumi@0832080.com さんが書きました:今回のお題とは関係無いですが,構造体にコンストラクタ/デストラクタがあったのは知らなかったです.
捕捉有難うございます.
C++では、構造体はクラスの一種です(もっといえば共用体もクラスの一種です)。
ですので、コンストラクタやデストラクタも持てますし、それ以外のメンバ関数も持てます。