使用 memset 和 memcpy 的问题

发布于 2024-08-26 23:50:52 字数 1426 浏览 5 评论 0原文

所以我正在尝试创建一个内存管理系统。为了做到这一点,我有一定数量的空间(由 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 行时不断出现段错误。在过去的一个小时左右的时间里,我们一直在尝试不同的想法,老实说,我们只是不知道错误发生在哪里。

::编辑2:: 我也将其作为评论发布,但我想我也将它放在这里,这样更容易找到...

我们的问题是我们有一个允许使用的已分配空间,由一个 malloc 调用指定128MB。我们只能使用这个,所以我们不能使用 malloc 将大小初始化为任何内容。我想,有没有办法在不初始化大小的情况下做到这一点。如果没有,是否可以在不使用 memcpy 的情况下获取标头设置为的 int 。

So I am trying to create a Memory Management System. In order to do this I have a set amount of space (allocated by malloc) and then I have a function myMalloc which will essentially return a pointer to the space allocated. Since we will then try and free it, we are trying to set a header of the allocated space to be the size of the allocated space, using memset.

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

We then need to be able to read this so we can see the size of it. We are attempting to do this by using memcpy and getting the first sizeof(int) bytes into a variable. For testing purposes we are just trying to do memset and then immediately get the size back. I've included the entire method below so that you can see all declarations. Any help would be greatly appreciated! Thanks!

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;
}

::Edit::
Sorry! When running this, we keep getting a seg fault when attempting to run the memcpy line. We have been playing with different ideas for the past hour or so and honestly just have no idea where the error is occurring.

::Edit2::
I also posted this as a comment, but figured I'd put it here as well, so it was easier to find...

Our problem is that we have an allocated space that we are allowed to work with, specified by one malloc call for 128MB. We can only use this, so we can't initialize size to anything using malloc. I guess, is there a way to do this without initializing size. If not, is there anyway to get the int that the header is set to without using memcpy.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

逐鹿 2024-09-02 23:50:52

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++ 指针的教程 除非您了解指针不会理解为什么这两行代码,背靠背,是一对糟糕的代码。

The prototype for memcpy is

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

The problem lies here:

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:
Please review this tutorial on pointers in C and C++ Unless you understand pointers you will not understand why those two lines of code, back to back, are a bad pair.

在风中等你 2024-09-02 23:50:52

您的代码中有许多错误 - 我不会一一介绍它们,而是给您一个它应该是什么样子的注释版本:

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;
}

You code has numerous bugs in it - rather than go through them one-by-one, I'll give you a commented version of what it should look like:

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;
}
饮惑 2024-09-02 23:50:52

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

void *size; is an uninitialized pointer, when you try to memcpy into it, your process will try to write this invalid location resulting seg fault.

断舍离 2024-09-02 23:50:52

您对 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 的低字节。

我不确定你打算做什么,所以我无法提供解决方案。

Your use of memset is very odd:

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

is equivalent to (assuming a 32 bit integer):

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

As you can see, it's setting each byte to the same value which is the lower byte of sizeBytes.

I'm not sure what you are intending to do so I can't offer a fix.

你与昨日 2024-09-02 23:50:52

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

IsBadWritePtr

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

1> 指针是垃圾或 NULL

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

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

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

   memcpy(s, t, 6);

if you are writing it in windows... you can use

IsBadWritePtr

To Verify that the calling process has write access to the specified range of memory.
There may be three reason

1>pointers is either garbage or NULL

2>the amount you're trying to copy is too much.

i.e. copying past the end of the block of memory. Potentially "backwards" copy of string-literal would also cause this behaviour

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

   memcpy(s, t, 6);
说好的呢 2024-09-02 23:50:52

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

In creating your own memory management system, now that you have learned what memset() does and doesn't, hopefully already knowing enough of the low level stuff that you know the difference between memcpy() and memmove(), your next step is to learn about "alignment" and about the guarantees that malloc() fulfills, but your code doesn't.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文