33 c memory-management realloc
我很难理解realloc是如何工作的.如果我malloc'ed缓冲区并将数据复制到该缓冲区,让我们说"AB":
+------------+
| A | B | \0 |
+------------+
Run Code Online (Sandbox Code Playgroud)
然后我重新分配了缓冲区,数据中是否会丢失(甚至是单个字节)?或者只是扩展缓冲区?:
+------------------------+
| A | B | \0 | ? | ? | ? |
+------------------------+
Run Code Online (Sandbox Code Playgroud)
码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void){
char* buffer = (char*) malloc( sizeof(char) * 3 );
strncpy(buffer, "AB", 2);
buffer = (char*) realloc(buffer, sizeof(char) * 6); /* Will there be any lost here? */
free(buffer);
return(0);
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*nan 52
realloc
增加块大小的A 将保留原始内存块的内容.即使内存块无法在放置时调整大小,也会将旧数据复制到新块中.对于realloc
减小块大小的方法,旧数据将被截断.
请注意,realloc
如果由于某种原因realloc
失败,您的通话将意味着您丢失了数据.这是因为realloc
返回失败NULL
,但在这种情况下原始内存块仍然有效,但由于你已经覆盖指针,你不能再访问它了NULL
.
标准模式是:
newbuffer = realloc(buffer, newsize);
if (newbuffer == NULL)
{
//handle error
return ...
}
buffer = newbuffer;
Run Code Online (Sandbox Code Playgroud)
另请注意,malloc
在C中不需要转换返回值,也就是说sizeof(char)
,根据定义,等于1
.
什么都没有丢失.但你真的应该测试realloc()
(和malloc()
之前)是否"有效".
同样,对malloc的返回值的强制转换最多也是多余的,并且它可能隐藏编译器在其缺失时将捕获的错误.
基于您想要字符串的假设,您的使用strncpy
是错误的
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *buffer = malloc(3);
if (buffer == NULL) /* no memory */ exit(EXIT_FAILURE);
strncpy(buffer, "AB", 2);
/* ATTENTTION! ATTENTION: your array is not a string.
** buffer[2] is not the zero string terminator */
// buffer = realloc(buffer, 6); /* Will there be any lost here? */
/* If realloc returns NULL, you've just lost the only pointer to
** the allocalted memory, by overwriting it with NULL.
** Always `realloc` to a temporary variable */
char *tmp_buffer = realloc(buffer, 6);
if (tmp_buffer == NULL) {
/* realloc failed */
} else {
/* realloc worked, no bytes lost */
buffer = tmp_buffer;
/* ATTENTION! ATTENTION: buffer is still not a string
** buffer[0] is 'A', buffer[1] is 'B',
** all other elements of buffer are indeterminate */
}
free(buffer);
return(0);
}
Run Code Online (Sandbox Code Playgroud)