c++ - 使用 malloc : why did it happen? 的内存分配导致堆损坏

标签 c++ c pointers memmove

好吧,我只是作为一个编程练习来尝试实现 memmove,当我尝试使用 malloc 时,我在 memmove 函数中遇到了内存访问冲突。这是函数:

//Start

void* MYmemmove (void* destination, const void* source, size_t num) { 

    int* midbuf = (int *) malloc(num); // This is where the access violation happens.
    int* refdes = (int *) destination; // A pointer to destination, except it is casted to int*
    int* refsrc = (int *) source; // Same, except with source
    for (int i = 0;num >= i;i++) { 
        midbuf[i] = *(refsrc + i); // Copy source to midbuf
    }
    for (int i = 0;num >= i;i++) { 
        refdes[i] = *(midbuf + i); // Copy midbuf to destination
    } 
    free(midbuf); // free midbuf 
    refdes = NULL; // Make refdes not point to destination anymore
    refsrc = NULL; // Make refsrc not point to source anymore
    return destination;
}

顺便说一句,我是指针的新手,所以如果有一些错误,请不要感到惊讶。 我做错了什么?

最佳答案

请小心其他建议!答案取决于您的 memmove 将如何使用。其他答案指出您应该更改 malloc 调用以考虑 int 的大小。但是,如果您的 memmove 函数将用于表示“移动此数量的 bytes”,那么实现将是错误的。我会转而使用 char*,因为它可以一次性解决多个问题。

此外,int 通常为 4 个字节,而 char 通常为 1 个字节。如果您收到的 void* 地址不是字对齐的(不是 4 字节的倍数),您将遇到一个问题:要复制一个不是字对齐的 int,您将不得不做不止一个读取和昂贵的位掩码。这是低效的。

最后,内存访问冲突发生了,因为您每次递增 midbuf int 指针,并且一次向前移动 4 个字节。但是,您只分配了 num bytes,因此最终会尝试访问已分配区域的末尾。

/** Moves num bytes(!) from source to destination */
void* MYmemmove (void* destination, const void* source, size_t num) { 

    // transfer buffer to account for memory aliasing
    // http://en.wikipedia.org/wiki/Aliasing_%28computing%29
    char * midbuf = (char *) malloc(num); // malloc allocates in bytes(!)
    char * refdes = (char *) destination;
    char * refsrc = (char *) source;

    for (int i = 0; i < num; i++) { 
        midbuf[i] = *(refsrc + i); // Copy source to midbuf
    }

    for (int i = 0; i < num; i++) { 
        refdes[i] = *(midbuf + i); // Copy midbuf to destination
    } 

    free(midbuf); // free midbuf
    // no need to set the pointers to NULL here.
    return destination;
}

通过逐字节复制,我们避免了对齐问题,以及 num 本身可能不是 4 字节的倍数的情况(例如 3,因此 int 对于该移动来说太大)。

关于c++ - 使用 malloc : why did it happen? 的内存分配导致堆损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12771276/

相关文章:

c++ - boost::fusion::for_each 中的函数对象不同于 std::for_each

c++ - OpenGL 矩阵乘法 C++

用 C 创建类似 shell 的程序

c - Realloc 导致错误(堆 block 超过请求的大小...)

c++ - 在 C++ 中调用指向成员函数的指针时出错

更改C中的指针

c++ - 将数组传递给函数——指针与引用(C++ 与 C)

c++ - C++中的构造函数和析构函数

c++ - 识别继承类的最佳方法

c - Linux 上的 feof() 在结束行晚一行返回 true