2013-09-04 7 views
6

私はコードをより効率的にしようとしています。私は次のようなものを持っています:新しいサイズが古いものと同じときのreallocの動作

typedef struct{ 
    ... 
    }MAP; 



    MAP* pPtr=NULL; 
    MAP* pTemp=NULL; 
    int iCount=0; 
    while (!boolean){ 
    pTemp=(MAP*)realloc(pPtr,(iCount+1)*sizeof(MAP)); 
    if (pTemp==NULL){ 
    ... 
    } 
    pPtr=pTemp; 
    ... 
    iCount++; 
    } 

メモリが動的に割り当てられています。コードをより効率的にするためにrealloc呼び出しを減らしたいと思います。新しいサイズが古いサイズと等しい場合、reallocがどのように動作するかを知りたいです。コールは単に無視されますか?

+1

OT:(iCount + 1)* sizeof(MAP)が少なくとももっとよく見えると感じます... – alk

+0

@alk:あなたは正しいです。それを変更します。 –

+0

ほとんどの実装ではおそらく同じポインタが返されますが、将来の割り当てを容易にするために割り当てられた領域を再配置する機会と同じサイズの 'realloc'を使用することがあります。 –

答えて

8

これは、標準のC.に指定されていないすべての標準Cが保証され:新しいオブジェクトの内容は、解放前の古いオブジェクトの内容と同じでなければならず、新しいサイズと古いサイズのうちの小さいものになります。

しかし、GNU libcを使用している場合は、明示的に同じアドレスを返すように言います。詳細はhereを参照してください。

指定した新しいサイズが古いサイズと同じ場合、reallocは何も変更せずに与えたものと同じアドレスを返すことが保証されています。

+2

'realloc'はgccではなく、GNU' libc'によって提供されます。これは単にコンパイラです。多くのシステムでは、gccはGNU libc以外のライブラリで使用されます。 –

+1

@Keith Thompson修正しました。指摘していただきありがとうございます。 –

3

サイズが変更されない場合は、reallocはノーオペレーションとして動作しませんが(ただし、これは妥当な方法です)、次のようにする必要はありません。 iCountは変更されていません.reallocを呼び出さないでください。

2

Cの標準では何が起こるのかが指定されていないため、実装の慈悲を受けています。渡されたポインタを返さない半分の実装を想像することはできませんが、安全なオプションは割り当てのサイズがあなた自身のコードで変更されているかどうかをチェックすることです。それは確かに関数呼び出しをスキップします。

(ところで、reallocからの戻り値をキャストしないでください。それは必要はありません、あなたは#include <stdlib.h>に忘れてしまった場合、それは未定義の動作を隠すことがあります。)

+0

私はreallocがNULLを返すかどうかを調べることが重要だと思います。なぜなら、失敗した場合、セグメンテーションフォールトに終わるからです。私が知る限り、出力がNULLの場合、オンラインで利用可能なすべてのreallocコールがチェックされます。 –

+0

@hhachem:割り当てサイズが変更されない場合は、呼び出しをスキップします。 –

関連する問題