6

という名前の別の構造体の配列を含む構造体にメモリを割り当てたいと考えていますtable。最後に関数へのポインターを割り当てると、linkedObjects配列内の変数が破損することがわかったので、動的メモリの処理が間違っていると思います。

これが私が今やっている方法です:

typedef struct Object {
    void *key;
    struct Object *top;
    struct Object *next;
} Object;

typedef struct Table{
    Object *linkedObjects;
    size_t size, originalSize;
    HashFcn hfun;
    PrintFcn pfun;
    ComparisonFcn fcomp;
} Table;

TableP CreateTable(size_t tableSize, HashFcn hfun, PrintFcn pfun, ComparisonFcn fcomp)
{
    int i;
    struct Table *table = malloc(sizeof(table));
    if (table==NULL)
    {
        ReportError(MEM_OUT);
        return NULL;
    }
    table->linkedObjects = NULL;
    table->linkedObjects  = malloc(tableSize * sizeof(Object));

    for(i=0;i<tableSize;i++)
    {

        table->linkedObjects[i].next = malloc( MAX_IN_LIST*sizeof(Object) );
        table->linkedObjects[i].top = malloc( MAX_IN_LIST*sizeof(Object) );
        table->linkedObjects[i].key = NULL;
        table->linkedObjects[i].top->key = NULL;
        table->linkedObjects[i].next->key = NULL;

        if (table->linkedObjects[i].next == NULL)
        {
            ReportError(MEM_OUT);
            return NULL;
        }
    }

    table->size = tableSize;
    table->originalSize = tableSize;
    table->hfun = hfun;
    table->pfun = pfun;
    table->fcomp = fcomp;
    return table;
}

編集:回答を反映するように関数コードを編集しました:

TableP CreateTable(size_t tableSize, HashFcn hfun, PrintFcn pfun, ComparisonFcn fcomp)
{
    int i;
    struct Table *table = malloc(sizeof(table));
    if (table==NULL)
    {
        ReportError(MEM_OUT);
        return NULL;
    }
    table->linkedObjects = NULL;
    table->linkedObjects  = malloc(tableSize * sizeof(Object));

    if (table->linkedObjects == NULL)
    {
        ReportError(MEM_OUT);
        return NULL;
    }

    for(i=0;i<tableSize;i++)
    {
        table->linkedObjects[i].next = NULL;
        table->linkedObjects[i].top = NULL;
        table->linkedObjects[i].key = NULL;
    }

    table->size = tableSize;
    table->originalSize = tableSize;
    table->hfun = hfun;
    table->pfun = pfun;
    table->fcomp = fcomp;
    //printf("%p\n", table->hfun);
    return table;
}

しかし、それでも最後に割り当てのポイントに到達すると、table->linkedObjects[0].keyそれは null であり、値は0x0get の値へのオーバーランです0x8048cc0。これは、次の行が実行されると発生します。

table->originalSize = tableSize;

別の編集:最後の呼び出しでランダムに発生することを確認しました(上記の行だけでなく):

table->size = tableSize;
table->originalSize = tableSize;
table->hfun = hfun;
table->pfun = pfun;
table->fcomp = fcomp;
4

3 に答える 3

5

struct Table *table = malloc(sizeof(table));

する必要があります

struct Table *table = malloc(sizeof(Table));

私は時々Cが好きです。

`

于 2012-12-25T18:22:21.253 に答える
1

いつものように、 の下で型名を使用する習慣を取り除きsizeofます。これは、メモリ割り当てがどのように見えるかです

Table *table = malloc(sizeof *table);
...
table->linkedObjects = malloc(tableSize * sizeof *table->linkedObjects);

これにより、最初の割り当ての「タイプミス」エラーも修正されます。

于 2012-12-25T18:34:43.267 に答える
0
table->linkedObjects[i].next = malloc( MAX_IN_LIST*sizeof(Object) );
table->linkedObjects[i].top = malloc( MAX_IN_LIST*sizeof(Object) );

これは意味がないようです。コレクションを表示するとき、コレクションへの単一のポインター (コレクション内の次のアイテムまたはコレクション内の最初のアイテム) を期待しnextます。topObject

次のことをするつもりでしたか:

for(i=0;i < (tableSize-1);i++)
{
    table->linkedObjects[i].top = table->linkedObjects[0];
    table->linkedObjects[i].next = table->linkedObjects[i+1];
    table->linkedObjects[i].key = NULL;
}

これにより、それぞれにメモリが割り当てられObject、後でポインタが設定されます。

于 2012-12-25T17:38:44.270 に答える