好吧,我只是作为一个编程练习来尝试实现 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/