2011-07-13 3 views
0

私はこのコードに関する質問があります。私は自分のフレームワークにこのコードを書いて、フレームワークをクラッシュさせました。しかし、以下のコードを1つのファイルに書き直すと、うまく動作します。私はちょうど不思議だった、以下のコードは、メモリの割り当てとそれを解放するための正しいですか? (特にmsg-> context_var.type = Fの一部について;) は、それは間違っているあなたにフレームワークをクラッシュさせるコードですが、1つのファイルで再生した場合、それは正常に動作しました

#include <stdio.h> 
#include <stdlib.h> 


typedef struct 
{ 
    int value; 
    int price; 
    int old; 
} type_t; 


typedef struct { 
    type_t   *type; 
} context_t; 


typedef struct { 
    context_t context_var; 
} send_request; 



void send_Message(send_request *msg) 
{ 

type_t *f = 0; 
f = malloc(sizeof(f)); 
msg->context_var.type = f; 
msg->context_var.type->price = 1; 
msg->context_var.type->value = 100; 
msg->context_var.type->old =120; 


printf("value of %d/n", msg->context_var.type->price); 
free(f); 
} 

int main() 
{ 

    send_request *msg = 0; 
    msg = (send_request *) malloc(sizeof(send_request)); 

    send_Message(msg); 
    free(msg); 
    return 0; 
} 

答えて

7

ありがとうございます。

f = malloc(sizeof(f)); /* Wrong */ 
f = malloc(sizeof(*f)); /* Better ? */ 

sizeof(f)あなたのマシン上のポインタのサイズがわかります。 sizeof(*f)のサイズを与え、オブジェクトはを指しています。あなたは、あなたがUndefined Behaviorを誘発している必要があるほど割り当てると@Perception

によって要求されたよう

EDIT。何かが起きることがあり(望ましい行動でさえ)、それはすべてプラットフォーム、環境(月面など)に依存します。

msg->context_var.type->value = 100; /* Writes beyond what's allocated. */ 

ので、「フレームワーク」のメモリレイアウトに応じて、これは単にいくつかのメモリと「仕事」を上書きする可能性がある、またはそれがクラッシュする可能性があります。率直に言って、私はすぐにクラッシュすると好きです。

+0

もう一つの方法は、宣言と代入を結合し、sizeof(type_t)をmallocに渡すことです。 –

+0

@MartinTörnwall私はそれが気に入っていますが、悲しいことに、非c99コンパイラ(clのような)を使うときは避けなければなりません。 – cnicutar

+0

@ MartinsTörnwall、宣言と割り当てを組み合わせるとどういう意味ですか?申し訳ありませんが、私はそれを取得しません.. – heike

0

context_tのインスタンスをヒープに割り当て、msg->context_var.typeは結果のポインタfの値を取得します。

msgsend_Message関数へのポインタパラメータなので、msgとその内容が関数の後に実行されたことについては信頼できる前提ができません。そのため、fが指し示すメモリを解放すると、ぶら下がったポインタがmsg->context_var.typeに残ります。

send_Messageが存在すると、それが指しているメモリにアクセスすると、まったく異なるものが含まれている可能性があるため、重大なものが破損する可能性があります(または0xdeadbeefへのポインタのような奇妙なものを読み込みます)。

+0

...しかし、実際の問題はおそらく上記のcnicutarによって記述されたものでしょう。私はそれを見逃して自分自身に敬意を表します。 :) –

+0

私はあなたのように最初は同じと思う。あなたは私も自由(msg-> context_var.type)を書きますか?私は自由(f)と自由(msg-> context_var.type)を試して、フレームワークは完全なクラッシュを示しました:D .. – heike

0

あなたは間違ったサイズを割り当てているだけではありません(cnicutarの答えを参照してください)。 - フレームワークによって渡されたメッセージにfをつけている場合は、関数を返す前に解放したくないでしょう。おそらく、フレームワークによって提供される他の機能を介して、後で解放する必要がありますか?

関連する問題