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 行时不断收到段错误。在过去的一个小时左右,我们一直在玩不同的想法,老实说,只是不知道错误发生在哪里。

::Edit2:: 我也将此作为评论发布,但我想我也会把它放在这里,所以更容易找到......

我们的问题是我们有一个允许使用的分配空间,由一个 malloc 调用指定为 128MB。我们只能使用这个,所以我们不能使用 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*/

EDIT1:请查看本教程关于 C 和 C++ 中的 指针 除非您了解指针,否则您将无法理解为什么这两行代码背靠背是一对不好的。

于 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* 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 回答
1

void *size;是一个未初始化的指针,当您尝试memcpy进入它时,您的进程将尝试写入此无效位置,从而导致段错误。

于 2010-04-01T04:36:02.940 回答
1

如果您在 Windows 中编写它...您可以使用

IsBadWritePtr

验证调用进程是否具有对指定内存范围的写访问权限。可能有三个原因

1>指针要么是垃圾要么是NULL

2>您尝试复制的数量太多。

即复制超过内存块的末尾。字符串文字的潜在“向后”副本也会导致这种行为

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

   memcpy(s, t, 6);
于 2010-04-01T04:44:32.110 回答
0

在创建自己的内存管理系统时,既然您已经了解了 memset() 做什么和不做什么,希望您已经了解了足够的底层知识,您知道 memcpy() 和 memmove() 之间的区别,下一步是了解“对齐”和 malloc() 满足的保证,但您的代码没有。

于 2010-04-01T07:23:45.280 回答