2

だから私はメモリ管理システムを作成しようとしています。これを行うために、(mallocによって割り当てられた)一定量のスペースがあり、次に、割り当てられたスペースへのポインターを本質的に返す関数myMallocがあります。次にそれを解放しようとするので、memsetを使用して、割り当てられたスペースのヘッダーを割り当てられたスペースのサイズに設定しようとしています。

memset(memPtr,sizeBytes,sizeof(int));

次に、これを読み取って、サイズを確認できるようにする必要があります。memcpyを使用し、最初のsizeof(int)バイトを変数に入れることで、これを実行しようとしています。テストの目的で、memsetを実行し、すぐにサイズを元に戻そうとしています。すべての宣言を確認できるように、以下にメソッド全体を含めました。どんな助けでも大歓迎です!ありがとう!

void* FirstFit::memMalloc(int sizeBytes){

node* listPtr = freelist;
void* memPtr;   

// Cycle through each node in freelist
while(listPtr != NULL)
{

    if(listPtr->size >= sizeBytes) 
    {
        // We found our space
        // This is where the new memory allocation begins
        memPtr = listPtr->head;
        memset(memPtr,sizeBytes,sizeof(int));

        void *size;
        memcpy(size, memPtr, sizeof(int));
        // Now let's shrink freelist
        listPtr->size = listPtr->size - sizeBytes;

        int *temp = (int*)listPtr->head + (sizeBytes*sizeof(int));  
        listPtr->head = (int*) temp;
        return memPtr;
    }

    listPtr = listPtr->next;
}

::編集:: ごめんなさい!これを実行すると、memcpy行を実行しようとすると、セグメンテーション違反が発生し続けます。私たちは過去1時間ほどさまざまなアイデアで遊んでいますが、正直なところ、エラーがどこで発生しているのかわかりません。

:: Edit2 :: これもコメントとして投稿しましたが、ここにも載せると思ったので見つけやすかったです...

私たちの問題は、128MBの1回のmalloc呼び出しで指定された、作業が許可されているスペースが割り当てられていることです。これしか使用できないため、mallocを使用してサイズを初期化することはできません。サイズを初期化せずにこれを行う方法はあると思います。そうでない場合は、memcpyを使用せずにヘッダーが設定されているintを取得する方法はありますか。

4

6 に答える 6

3

memcpyのプロトタイプは

void * memcpy ( void * destination, const void * source, size_t num );

問題はここにあります:

void *size; /* you haven't initialized this variable, and then you're writing to what it points to*/
memcpy(size, memPtr, sizeof(memPtr)); /* because size points to uninitialized memory it seg faults*/

編集1:CおよびC ++のポインターに関するこのチュートリアルを確認してください。ポインター を理解しない限り、これらの2行のコードが連続して悪いペアである理由を理解できません。

于 2010-04-01T04:36:46.793 に答える
2

memsetの使用は非常に奇妙です:

memset(memPtr,sizeBytes,sizeof(int));

(32ビット整数を想定)と同等です:

*((char *)memPtr + 0) = (sizeByte & 0xFF);
*((char *)memPtr + 1) = (sizeByte & 0xFF);
*((char *)memPtr + 2) = (sizeByte & 0xFF);
*((char *)memPtr + 3) = (sizeByte & 0xFF);

ご覧のとおり、各バイトはの下位バイトである同じ値に設定されていますsizeBytes

あなたが何をしようとしているのかわからないので、修正を提供することはできません。

于 2010-04-01T06:50:59.877 に答える
1

void *size;は初期化されていないポインタです。これにアクセスmemcpyしようとすると、プロセスはこの無効な場所を書き込もうとし、セグメンテーション違反が発生します。

于 2010-04-01T04:36:02.940 に答える
1

あなたがそれをウィンドウズで書いているなら...あなたは使うことができます

IsBadWritePtr

呼び出し元のプロセスが指定された範囲のメモリへの書き込みアクセス権を持っていることを確認します。3つの理由が考えられます

1>ポインタはガベージまたはNULLのいずれかです

2>コピーしようとしている量が多すぎます。

つまり、メモリブロックの終わりを超えてコピーします。文字列リテラルの「逆方向」のコピーもこの動作を引き起こす可能性があります

char *s = "Hello";
char   t[10];

   memcpy(s, t, 6);
于 2010-04-01T04:44:32.110 に答える
1

あなたのコードにはたくさんのバグがあります-それらを一つずつ調べるのではなく、それがどのように見えるべきかについてのコメント付きバージョンをあなたに与えます:

void* FirstFit::memMalloc(size_t sizeBytes)  // size_t is the appropriate type for memory sizes
{
    node* listPtr = freelist;
    void* memPtr;   
    // The actual allocation needs to be bigger, to have space to hold the size itself.
    size_t allocSize = sizeBytes + sizeof allocSize;

    // Test to make sure that allocSize didn't wrap around to zero
    if (allocSize < sizeBytes)
    {
        return NULL;
    }

    // Cycle through each node in freelist
    while(listPtr != NULL)
    {

        if(listPtr->size >= allocSize) 
        {
            // We found our space
            // This is where the new memory allocation begins
            memPtr = listPtr->head;

            // Copy the size to the start of the memory region
            memcpy(memPtr, &allocSize, sizeof allocSize);

            // Increment the pointer to be returned past the size
            char *tempPtr = (char *)memPtr;
            memPtr = (void *)(tempPtr + sizeof allocSize);

            // Shrink the block
            listPtr->size -= allocSize;
            tempPtr = (char *)listPtr->head;
            listPtr->head = (void *)(tempPtr + allocSize);

            // TODO: If the block is now zero-sized, remove it from the linked list

            return memPtr;
        }

    listPtr = listPtr->next;
    }

    /* No space */
    return NULL;
}
于 2010-04-01T06:30:07.343 に答える
0

独自のメモリ管理システムを作成する際に、memset()が何をするか、何をしないかを学習したので、memcpy()とmemmove()の違いを知っている低レベルのものを十分に理解していることを願っています。次のステップは次のとおりです。 「アラインメント」とmalloc()が満たす保証について学ぶために、しかしあなたのコードはそうではありません。

于 2010-04-01T07:23:45.280 に答える