pit-rayの備忘録

開発中に得た知識を記事にしていくブログ

<C言語>malloc()+memset()とcalloc() ゼロクリアする場合における違い

 

今回は開発していて気になったことがあったのでググってみました。

言語はCです。

 

最初の記事にも書いたのですが、私自身、プログラミング歴が長いわけではないため、参考程度に見ていただければ幸いです。

 

 

 

まず、今回気になったことは

malloc()+memset()によるゼロクリアとcalloc()によるゼロクリアは何が違うのだろうか

ということです。

 

まず、それぞれの関数の定義等を見ていきましょう。

 

メモリ確保を行う関数。stdlib.hに定義されている。

定義:void *malloc(size_t size)

戻り値:確保したメモリの先頭アドレス

参考:malloc - Wikipedia

 

  • memset

指定したメモリブロックから指定したバイト数の範囲に指定した文字データを書き込む関数。string.hに定義されている。

つまりは、指定した範囲を指定した文字で埋める関数です。

今回はこの関数を利用して上記malloc関数で確保したメモリをmemset関数で初期化(ゼロクリア)するということです。(このことを以下malloc()+memset()と略す )

定義:void *memset(void *s, int c, size_t)

戻り値:sの先頭アドレス

参考:memset - Wikipedia

 

  • calloc

メモリの確保とその初期化(ゼロクリア)する関数。stdlib.hに定義されている。

これはmalloc関数にゼロクリア機能が付いたもの。

定義:void *calloc(size_t nelements, size_t bytes)

戻り値:確保したメモリの先頭アドレス

参考:malloc-関連する関数 - Wikipedia

 

 

ここでmemset()の初期化処理とcalloc()の初期化処理は何が違うのかということが気になったわけです。

その為、ググってみたところ、以下のようなページがありました。

c - Why malloc+memset is slower than calloc? - Stack Overflow

ここでの質問者さんの投稿をまとめると

日々、calloc()をmalloc()+memset()として考えてるんだけど、興味本位でベンチマーク測ってみたんだ。そしたらmalloc()+memset()はcalloc()よりも約10倍くらい遅いんだけど...ど、どゆこと??

といった主旨のことを書いてます。

Answersに以下のように書かれていました。

原文

 The short version: Always use calloc() instead of malloc()+memset(). In most cases, they will be the same. In some cases, calloc() will do less work because it can skip memset() entirely. In other cases, calloc() can even cheat and not allocate any memory! However, malloc()+memset() will always do the full amount of work.

 

 訳

質問に対する回答の要約:あなたはcalloc()malloc()+memset()の代わりとしていつも使ってもいいです。calloc()malloc()+memset()とほぼ同じものとして機能するはずなので。でも稀に、calloc()memset()の処理を行わず、malloc()の処理のみ行うことがあったりします。他には、calloc()は誤魔化して、まったくメモリを割り当てないことだってあります。それに対して、malloc()+memset()は確実にゼロクリアを行います。

 この訳は全く持って正しいものではないので、他サイトなどに転載しないようにご協力お願いします。ここでは大体の意味を掴むために訳しております。

 

つまり、memset()のほうがcalloc()よりも確実にゼロクリアを行うといった感じでしょうか。

 

しかし、上記の参考サイトの質問者が仰っている通り、calloc()のほうがmemset()+malloc()よりも高速らしいです。

この件に関しての記事がありました。

malloc+memsetとcallocの違いについて

 

私の記事よりも詳しく書かれています。

もう少し深いところを知りたい場合、是非アクセスしてみてください。

 

結果的に言いますと、どちらがイイとは言えません。

どちらもそれぞれメリット・デメリットがあるみたいです。

素人の私にしてみるとお腹一杯です...(;´Д`)

 

まとめると

Q -ゼロクリアするうえでのmemset()とcalloc()の違いは?

A -「確実性」memset() >calloc()

  「速度面」memset()<calloc()

といった感じでしょうか。

 

何かこの記事にご不明な点や変な個所がありましたら、コメントにて指摘して頂けると幸いです。また、私は初心者みたいなものなので、意見など書いていただけると助かります。

何度も言いますが...あくまで備忘録であることをお忘れなく。

それではまた。