0

次のコードは正常に動作します。


typedef struct node_s {
    void *data;
    struct node_s *next;    
} NODE;

typedef struct test_s
{
    int asdf;
}TEST;
NODE *list_create(void *data)
{
    NODE *node;
    if(!(node=malloc(sizeof(NODE)))) return NULL;
    node->data=data;
    node->next=NULL;
    return node;
}

NODE *list_insert_after(NODE *node, void *data)
{
    NODE *newnode;
    newnode=list_create(data);
    newnode->next = node->next;
    node->next = newnode;
    return newnode;
}

NODE *list, *second, *third;

void localstructtest()
{
    TEST t;
    t.asdf = 10;

    third = list_insert_after(second, (void*)&t);
}

int main()
{
    TEST th;
    TEST* hrm;

    /* Create initial elements of list */
    list=list_create((void*)"First");
    second=list_insert_after(list, (void*)"Second");
    localstructtest();

    hrm = (TEST*)third->data;
    th = *hrm;
    return 1;
}

構造体は main 以外の関数でローカルに作成されますが、localstructtest() のスコープ外のリンク リストからデータを取得できました。ローカル変数はスタック上に作成されますが、これはこの構造体にも当てはまりますか? それとも実際にヒープ上に作成され、ポインター/参照は有効なままですか? テストしたとき、これはひどく失敗すると予想していました。私は C++ プログラマーであり、C に参照渡しがないことの影響をおそらく完全には理解していないことを認めます。このように構造体データを使用しても問題ない場合、データはいつ取得されますか?解放された?

ありがとう!

4

2 に答える 2

2

未定義の動作月の満ち欠けに応じて、機能する場合と機能しない場合があり、コンピューターがイボイノシシに変わる可能性があります。

真剣に: これは小さなサンプル プログラムでは機能するかもしれませんが、プログラムが大きくなるにつれて、あなたの顔に爆発することは間違いありません。

参照渡しについては、C ではポインターを渡すことでそれを行います。基本的なメモリ割り当てのルールは C++ と同じです。ローカルstructはスタックに割り当てられ、スコープ外になると破棄されます。主な違いは、デストラクタがないため、完全な RAII を取得できないことです。

于 2011-03-23T17:12:16.790 に答える
1

ほとんどのシステムで機能する理由は、フレームがポップされたときにスタックがゼロにされないためです。プログラムに一見関係のない小さな変更を加えると、プログラムは機能しなくなります。

int junk()
{
    char junkdata[100] = {0};
    return 42;
}

int main()
{
    TEST th;
    TEST* hrm;

    /* Create initial elements of list */
    list=list_create((void*)"First");
    second=list_insert_after(list, (void*)"Second");
    localstructtest();
    junk();

    hrm = (TEST*)third->data;
    th = *hrm;
    return 1;
}

これは、junk() がスタックの構造をゼロで上書きするために発生します。

于 2011-03-23T17:22:29.590 に答える