2010-12-13 17 views
1

私はSCIPというライブラリを使うコードを書いています(最適化の問題を解決します)。ライブラリ自体は、.aファイルのセットを作成し、次にバイナリを作成するか、または共有オブジェクトのセットを作成するという2つの方法でコンパイルできます。どちらの場合も、SCIPは独自の、かなり大きいMakefileでコンパイルされます。mallocがメモリを初期化する原因は何ですか?

2つの実装があります.1つは.aファイル(このプログラムは1と呼ばれます)でコンパイルされ、もう1つは共有オブジェクトとリンクされます(このプログラムは2と呼ばれます)。プログラム1はSCIP提供のmakefileを使ってコンパイルされますが、プログラム2は私自身のより簡単なmakefileを使ってコンパイルされます。

私が遭遇した動作は、私が書いたコードではなく、SCIPコードで発生します。次のようにコードの抜粋は以下のとおりです。

void* BMSallocMemory_call(size_t size) 
{ 
    void* ptr; 

    size = MAX(size, 1); 
    ptr = malloc(size); 

    // This is where I call gdb print statements. 

    if(ptr == NULL) 
    { 
     printf("ERROR - unable to allocate memory for a SCIP*.\n"); 
    } 
    return ptr; 
} 

void SCIPcreate(SCIP** A) 
{ 
    *A = (SCIP*)BMSallocMemory_call(sizeof(**(A))) 
    . 
    . 
    . 
} 

私はgdbの中で、このコードをデバッグし、何が起こっているか確認し、*((SCIP*)(ptr))の内容を表示するために、BMSallocMemory_call()をステップ実行した場合、私は次のような出力が得られます。

プログラム1つのGDB出力:

289 size = MAX(size, 1); 
(gdb) step 
284 { 
(gdb) 
289 size = MAX(size, 1); 
(gdb) 
290 ptr = malloc(size); 
(gdb) print ptr 
$1 = <value optimised out> 
(gdb) step 
292 if(ptr == NULL) 
(gdb) print ptr 
$2 = <value optimised out> 
(gdb) step 
290 ptr = malloc(size); 
(gdb) print ptr 
$3 = (void *) 0x8338448 
(gdb) print *((SCIP*)(ptr)) 
$4 = {mem = 0x0, set = 0x0, interrupt = 0x0, dialoghdlr = 0x0, totaltime = 0x0, stat = 0x0, origprob = 0x0, eventfilter = 0x0, eventqueue = 0x0, branchcand = 0x0, lp = 0x0, nlp = 0x0, relaxation = 0x0, primal = 0x0, tree = 0x0, conflict = 0x0, cliquetable = 0x0, transprob = 0x0, pricestore = 0x0, sepastore = 0x0, cutpool = 0x0} 

プログラム2 gdbの出力:

289 size = MAX(size, 1); 
(gdb) step 
290 ptr = malloc(size); 
(gdb) print ptr 
$1 = (void *) 0xb7fe450c 
(gdb) print *((SCIP*)(ptr)) 
$2 = {mem = 0x1, set = 0x8232360, interrupt = 0x1, dialoghdlr = 0xb7faa6f8, totaltime = 0x0, stat = 0xb7fe45a0, origprob = 0xb7fe4480, eventfilter = 0xfffffffd, eventqueue = 0x1, branchcand = 0x826e6a0, lp = 0x8229c20, nlp = 0xb7fdde80, relaxation = 0x822a0d0, primal = 0xb7f77d20, tree = 0xb7fd0f20, conflict = 0xfffffffd, cliquetable = 0x1, transprob = 0x8232360, pricestore = 0x1, sepastore = 0x822e0b8, cutpool = 0x0} 

私が考えることができる唯一の理由は、プログラム1またはSCIPのmakefileには、mallocが割り当てるメモリを初期化するようなオプションがいくつかあることです。コンパイルされた実装で構造体がなぜ初期化され、共有オブジェクトの実装に含まれていないのかを知る必要があります。

+0

どのOSが対応していますか? – sharptooth

答えて

1

malloc-edメモリの初期化は実装に依存する可能性があります。実装はパフォーマンス上の理由から自由ではありませんが、デバッグモードなどでメモリを初期化できます。

もう1つ注意してください。初期化されていないメモリでさえ、ゼロを含むことがあります。

2

私は、2つのプログラムがどのように構築されているかとは違いがあるとは思っていません。

mallocは、割り当てられたメモリを初期化しません。あなたが戻った記憶がゼロで満たされていることは偶然起こるかもしれません。たとえば、ちょうど開始されたプログラムは、しばらくの間実行されていたメモリを割り当て/割り当て解除するプログラムよりもゼロ充填のメモリをmallocから得る可能性が高くなります。あなたが興味のある、次の過去の質問を見つけることが

編集:

+0

私はもう少しコードを演奏し、callocのためにmallocを交換しました。すべてを再コンパイルした後、私は同じ動作をします。つまり、プログラム2のSCIP構造はまだ初期化されていません。私はさらに混乱しています。 プログラム2は実際にはPythonコードであり、SWIG(Python-Cインタフェースジェネレータ)によって作成されたSOを呼び出しています。私は最近、SCIP共有オブジェクトにアクセスするための標準的なCコードを書き、ピクチャからPythonとSWIGを削除し、ptrが割り当てられると、mallocかcallocが使用されているかどうかにかかわらず、再び 'ゼロアウト。 – Andy

+0

@Andyあなたの最初の点に関しては、これは確かに非常に奇妙です。あなたが使用している正確な 'calloc'呼び出しは何ですか?その直後に構造体はゼロではありませんか? – NPE

+0

"ptr = calloc(1、size);"、これは正しいと思いますか? – Andy

0

this threadによると、メモリはゼロになりますアプリケーションに最初に渡されたときに埋められます。したがって、malloc()への呼び出しによってプログラムのヒープが増加した場合、「新しい」メモリはゼロで埋められます。検証する

一つの方法は、それが直接、メモリを初期化するコードが含まれているかどうか、それはかなり明確にしなければならないこと、ちょうどあなたのルーチンからmalloc()をステップすることはもちろんです。

関連する問題