C:使用realloc时出现内存错误
考虑玩具代码如下:C:使用realloc时出现内存错误,c,memory-management,heap-memory,C,Memory Management,Heap Memory,考虑玩具代码如下: #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_STRING_LENGTH (5000) typedef struct request_body_s { char *data; size_t size; // in bytes } request_body_t; int do_something(request_body_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STRING_LENGTH (5000)
typedef struct request_body_s {
char *data;
size_t size; // in bytes
} request_body_t;
int do_something(request_body_t *request_body) {
char* content = read_content_elsewhere("/dir/content");
size_t size = strlen(content) * sizeof(char);
request_body->data = (char *) realloc(request_body->data, size + 1);
if (request_body->data == NULL)
return 0;
else {
request_body->size = size;
strncpy(request_body->data, content, MAX_STRING_LENGTH);
return 1;
}
}
int main(int argc, char *argv[]) {
request_body_t request_body;
request_body.data = malloc(1);
request_body.size = 0;
if (do_something(&request_body))
printf("Read!\n");
else {
printf("Error!\n");
exit(0);
}
free(request_body.data);
request_body.size = 0;
}
*** free(): invalid next size (fast): 0x0000000001594570 ***
什么(当然)是错的,为什么?谢谢你的建议。我相信问题就在这里:
strncpy(request_body->data, content, MAX_STRING_LENGTH);
根据您的目标(描述不清楚),我建议:
strncpy(request_body->data, content, size > MAX_STRING_LENGTH ? MAX_STRING_LENGTH : size );
我认为问题就在这里:
strncpy(request_body->data, content, MAX_STRING_LENGTH);
根据您的目标(描述不清楚),我建议:
strncpy(request_body->data, content, size > MAX_STRING_LENGTH ? MAX_STRING_LENGTH : size );
strncpy
复制字符串的前n个字符,在您的示例中为5000。如果源字符串小于n
(此处为5000),则其余字符串用零填充,因此您正在进一步访问buffer的末尾,这将导致未定义的行为
你需要:
strcpy(request_body->data, content);
在这里使用strcpy是安全的,因为我们可以确保由realloc分配的内存足够大,因为您可以使用realloc
顺便说一句,根据定义,
*sizeof(char)
始终为1,因此不需要*sizeof(char)
。strncpy
复制字符串的前n个字符,在您的情况下为5000。如果源字符串小于n
(此处为5000),则其余字符串用零填充,因此您正在进一步访问buffer的末尾,这将导致未定义的行为
你需要:
strcpy(request_body->data, content);
在这里使用strcpy是安全的,因为我们可以确保由realloc分配的内存足够大,因为您可以使用realloc
顺便说一句,根据定义,*sizeof(char)
始终为1,因此不需要*sizeof(char)
。如中所述
如果src的长度小于n,strncpy()会将额外的空字节写入dest,以确保总共写入n个字节
因此,通过使用strncpy(request\u body->data,content,5000)代码>,则在缓冲区外写入许多“\0”。您不应该这样做,这是一种未定义的行为,在本例中,您使用的是免费使用的“元数据”,因此它会崩溃
在这里,最好使用strcpy
(并确保在末尾添加“\0”)或memcpy
,因为您知道要写入的大小
而且,sizeof(char)很可能一直都是1,所以它也没用
如果src的长度小于n,strncpy()会将额外的空字节写入dest,以确保总共写入n个字节
因此,通过使用strncpy(request\u body->data,content,5000)代码>,则在缓冲区外写入许多“\0”。您不应该这样做,这是一种未定义的行为,在本例中,您使用的是免费使用的“元数据”,因此它会崩溃
在这里,最好使用strcpy
(并确保在末尾添加“\0”)或memcpy
,因为您知道要写入的大小
而且,和sizeof(char)很可能一直都是1,所以它也没用。您是否尝试释放整个请求体
?您的示例程序缺少某些部分,并且还包含其他错误。请准备一个最小的工作示例。您知道您可以传递一个空指针到realloc()
,换句话说,您不需要第一次调用malloc()
。man strncpy():[…]如果src的长度小于n,strncpy()会向dest写入额外的空字节,以确保总共写入n个字节。[…]
。以后应该尝试使用valgrind之类的调试器。如果您将(固定版本的)代码传递给valgrind,请正确注意错误在第19行(strncpy(…)
)。这是一个非常有用的c开发工具!您是否尝试释放整个请求\u正文
?您的示例程序缺少某些部分,并且还包含其他错误。请准备一个最小的工作示例。您知道您可以传递一个空指针到realloc()
,换句话说,您不需要第一次调用malloc()
。man strncpy():[…]如果src的长度小于n,strncpy()会向dest写入额外的空字节,以确保总共写入n个字节。[…]
。以后应该尝试使用valgrind之类的调试器。如果您将(固定版本的)代码传递给valgrind,请正确注意错误在第19行(strncpy(…)
)。这是一个非常有用的c开发工具<代码>请求正文->数据
已经专门为内容
调整大小,因此在这种情况下,使用strcpy
而不是strncpy
是合适的。请求正文->数据
已经专门为内容
调整大小,因此,在这种情况下,使用strcpy
而不是strncpy
是合适的。