【发布时间】:2021-12-28 02:16:13
【问题描述】:
您能否检查一下这段代码,看看为什么我在不使用 memcpy 的情况下实现 realloc 函数不起作用?我试图找出一种将有效负载大小和标签从一个块传输到另一个块的方法。尝试运行此代码时出现无效指针错误。
如何在不使用 memcpy 或任何其他本机 c 内存复制功能的情况下将有效负载从一个块传输到另一个块。
void* realloc(void* ptr, size_t size) {
BlockInfo * oldBlockInfo;
BlockInfo* newBlockInfo;
size_t ptrSize;
void* newPtr;
if(ptr == NULL){
return malloc(size);
}
else{
if(size == 0){
free(ptr);
return NULL;
}
}
oldBlockInfo = (BlockInfo*) UNSCALED_POINTER_SUB(ptr, WORD_SIZE);
ptrSize = SIZE(oldBlockInfo->sizeAndTags); //getting the size of the old block
//checking size
if (ptrSize >= size){//if old size is greater or equal return old pointer
return ptr;
}
else{
newPtr = malloc(size);
newBlockInfo = (BlockInfo*)UNSCALED_POINTER_ADD(newPtr,WORD_SIZE);
ptrSize = SIZE(newBlockInfo->sizeAndTags);
for (int i = WORD_SIZE;i<ptrSize;i+=WORD_SIZE){
newBlockInfo ->sizeAndTags = oldBlockInfo ->sizeAndTags;
newBlockInfo = newBlockInfo ->next;
oldBlockInfo = oldBlockInfo ->next;
}
}
//examine_heap();
free(ptr);
return newPtr;
}
这是一个使用 memcpy 实现 realloc,但我不能使用 memcpy
void *mm_realloc (void *ptr, size_t size) {
int minsize;
void *newptr;
// Allocate new block, returning NULL if not possible.
newptr = malloc (size);
if (newptr == NULL) return NULL;
// Don't copy/free original block if it was NULL.
if (ptr != NULL) {
// Get size to copy - mm_getsize must give you the size of the current block.
// But, if new size is smaller, only copy that much. Many implementations
// actually reserve the 16 bytes in front of the memory to store this info, e.g.,
// +--------+--------------------------------+
// | Header | Your data |
// +--------+--------------------------------+
// ^
// +--- this is your pointer.
// <- This is the memory actually allocated ->
minsize = mm_getsize (ptr);
if (size < minsize)
minsize = size;
// Copy the memory, free the old block and return the new block.
memcpy (newptr, ptr, minsize);
free (ptr)
}
return newptr;
}
【问题讨论】:
-
编辑问题以提供minimal reproducible example。
-
为什么在“返回旧指针”的评论后面有
return 0;? -
为什么需要将标签复制到新区块?
malloc()在新块中设置正确的标签。您应该只复制有效负载。 -
循环应该只复制旧块的大小,而不是新块。
-
这是一个很好的观点。但是我是c新手,如何将有效负载与块分开。