问题使用memset和memcpy

时间:2010-04-01 04:16:31

标签: c memory-management memset

所以我正在尝试创建一个内存管理系统。为了做到这一点,我有一定量的空间(由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 :: 我也发布了这个评论,但我想也把它放在这里,所以更容易找到......

我们的问题是我们有一个允许使用的分配空间,由一个128MB的malloc调用指定。我们只能使用它,所以我们不能使用malloc将大小初始化为任何东西。我想,如果没有初始化大小,有没有办法做到这一点。如果没有,无论如何都要获得标头设置的int而不使用memcpy。

6 个答案:

答案 0 :(得分: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: 请查看this tutorial on pointers in C and C++除非您理解指针,否则您将无法理解为什么这两行代码背靠背是一对糟糕的。

答案 1 :(得分: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的低字节。

我不确定你打算做什么,所以我无法提供修复。

答案 2 :(得分:1)

void *size;是一个未初始化的指针,当你尝试memcpy进入它时,你的进程会尝试写这个无效的位置导致seg错误。

答案 3 :(得分:1)

如果你在windows中写它...你可以使用

IsBadWritePtr

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

1>指针是垃圾或NULL

2>您尝试复制的金额太多了。

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

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

   memcpy(s, t, 6);

答案 4 :(得分: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;
}

答案 5 :(得分:0)

在创建自己的内存管理系统时,既然你已经了解了memset()的作用和不行,那么希望已经知道了足够的低级内容,你知道memcpy()和memmove()之间的区别,你的下一步是了解“对齐”以及malloc()实现的保证,但是你的代码没有。