0

失敗すると予想される次のコードがありますが、正しく機能しているようです。これが何らかのセグメンテーション違反を引き起こさない理由に混乱しています。

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

struct entry {
    int foo;
};

struct table {
    int size;
    struct entry* entries;
};

typedef struct table *Table;
typedef struct entry Entry;

int main() {
    Table table = malloc(sizeof(struct table));
    table->entries = malloc(sizeof(struct entry) * 1);
    (table->entries)[5].foo = 5;
    for (int i = 0; i < 10; i++) {
        printf("Entry #%d: %d\n",i,(table->entries)[i].foo);
    }
}

table->entries の 1 つのエントリに十分なスペースを malloc しただけなので、0 以外のインデックスへのアクセスは範囲外になると予想していました。しかし、このプログラムを実行すると、インデックス 5 のエントリの foo 値として 5 が出力され、残りは 0 として出力されます。これは正しい動作です。なぜこれが失敗しないのですか?

4

5 に答える 5

2

他の誰かがより適切に言うでしょうが、未定義の動作は未定義です。

定義されていません。それはうまくいくかもしれません。そうではないかもしれません。

それはすべて、それらのメモリの場所に何があるかによって異なります。

悪い場所を 1 つ書きました。あなたは他のいくつかを読みました。あなたはたまたま重要なものを打っていませんでした。

malloc された領域をはるかに超えて 1 つの単語を書きました。おそらく、malloc のデータ構造に書き込んだために問題を引き起こす計算をさらに行った場合。そうでないかもしれない。

于 2013-10-01T02:01:48.183 に答える
0
#include <stdio.h>
#include <stdlib.h>

struct entry {
    int foo;
};

struct table {
    int size;
    struct entry* entries;
};

typedef struct table *Table;
typedef struct entry Entry;

int main() {
    Table table =(table)malloc(sizeof(struct table));
    table->entries =(entry*)malloc(sizeof(struct entry) * 10);
    (table->entries)[5].foo = 5;
    for (int i = 0; i < 10; i++) {
        printf("Entry #%d: %d\n",i,(table->entries)[i].foo);
    }
}

まず、(void*) 型を を使用するときに必要なポインター型に変換する必要がありますmalloc。次に、エントリ ポインタのみを割り当てます。つまり、(table->entries)[5].foo を使用すると、メモリに不正にアクセスする可能性があるため、危険な動作になります。最後に、foo印刷する前に初期化する必要があります。ルールに従う必要があります。そのようなコードを記述しないでください。

于 2013-10-01T02:14:48.897 に答える