0

Cプログラムで単純なメモリマネージャー(実際にはメモリトラッカーと言うべきです)を書こうとしています。

私は基本的に、割り当てられたブロックの二重にリンクされたリストを作成しており、各ブロックの開始時に前と次にポインターを置きます。Malloc プロシージャは次のようになります。

    typedef struct MemUnit TMemUnit;
    struct tMemUnit
    {
        TMemUnit *prev;
        TMemUnit *next;
    }

    TMemUnit *new = malloc(sizeof(TMemUnit) + wantedSize);
    if (new == NULL)
        /* ERROR */
    else
    {
        if (memFirst == NULL) {
            memFirst = new;
            memLast = new;
            new->prev = NULL;
            new->next = NULL;
        } else {
            new->prev = memLast;
            new->next = NULL;
            memLast->next = new;
            memLast = new;
    }
    return (void *)(new + sizeof(TMemUnit));

問題は、以前はなかった場所でのセグメンテーション違反です。

Valgrind も無効な読み取り/書き込みエラーを返します。

==22872== Invalid write of size 4
==22872==    at 0x400FF1: main (test-memory.c:40)
==22872==  Address 0x54d51b0 is not stack'd, malloc'd or (recently) free'd

このエラーに対して割り当てられたブロックのアドレスを出力すると (wantedSize = 20 * sizeof(int)、最初の int を書き込もうとしています)、それらは問題ないように見えます:

new --> 0x54d5030
new + sizeof(TMemUnit) + wantedSize --> 0x54d5430

どこが間違っているのかわかりません。

ありがとう

4

3 に答える 3

2

問題は次の場所にある可能性があります。

return (void *)(new + sizeof(TMemUnit));

ポインタnewの型はTMemUnit *であるため、C ポインタ演算の規則により、sizeof(TMemUnit) * sizeof(TMemUnit)バイトが追加されますが、これは多すぎます。代わりに、次を試してください。

return (void *)((char *)new + sizeof(TMemUnit));
于 2012-11-03T21:26:55.420 に答える
0

return (void*)(new + 1) の代わりに return (void*)(new + sizeof(TMemUnit)) を試してください

ポインター演算 (p+n) は、すでに sizeof(*p) の単位でカウントされています。

于 2012-11-03T21:26:05.280 に答える
0

あなたがしたいかもしれませんreturn (void *)((char *)new + sizeof(TMemUnit));

于 2012-11-03T21:27:05.103 に答える