提问人:Akiyuu 提问时间:11/19/2022 最后编辑:Akiyuu 更新时间:11/19/2022 访问量:113
C:使用动态内存分配存储元素时堆缓冲区溢出
C: Heap Buffer Overflow when Storing Elements Using Dynamic Memory Allocation
问:
我正在编写一个 C 程序来存储,然后使用动态内存分配打印出通过 stdin 给出的所有字符串。 它会提示用户输入,直到它读取“文件末尾”(EOF、ctrl + d)。 我假设没有一行长度超过 255 个字符。
我对 C 编码相对较新,对使用 malloc() 函数也很陌生,所以如果我犯了一些明显的菜鸟错误,请耐心等待。请提供建议并帮助我修复我的程序。:)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER 255
int main(void)
{
char line[BUFFER];
int item = 0;
char** data = malloc(sizeof(char*));
for(;;)
{
printf("Enter string %d: ", item + 1);
if (fgets(line, BUFFER, stdin) == NULL)
{
break;
}
else
{
fgets(line, BUFFER, stdin);
}
data = realloc(data, sizeof(void *) * (item + 1));
data[item] = malloc(sizeof(char) * strlen(line));
memcpy(data[item], line, strlen(line));
item++;
}
printf("\n\nElements:\n");
for(int j = 0; j < item; j++)
{
printf("%s",data[j]);
free(data[j]);
}
free(data);
return 0;
}
我首先担心的是,我的程序会提示用户每次增量输入一个字符串输入两次。这不应该发生,并且应该在更新 的计数时不断询问用户。item
item
此外,我的程序没有存储正确输入的字符串;当尝试访问和打印我存储的字符串时,它会返回缓冲区溢出消息。我以前从未见过类似的错误:
==20==错误:AddressSanitizer:地址0x602000000052在 pc 0x55a8453c7865 bp 0x7ffd578edac0 sp 0x7ffd578ed280 上堆缓冲区溢出 在螺纹 T0 处读取尺寸 3 0x602000000052 #0 0x55a8453c7864 in printf_common(void*, char const*, __va_list_tag*) asan_interceptors.cpp.o #1 __interceptor_vprintf 中的0x55a8453c819a (/home/run+0xb119a) (BuildId: abfaad925a09237bc199a1c2ac9a7d328268e42f) #2 printf 中的0x55a8453c8277 (/home/run+0xb1277) (BuildId: abfaad925a09237bc199a1c2ac9a7d328268e42f) #3 在 main /home/main.c:39:9 中0x55a84543014d #4 0x7f08c84fe28f __libc_start_call_main /usr/src/debug/glibc/csu/ 中。/sysdeps/nptl/libc_start_call_main.h:58:16 #5 __libc_start_main /usr/src/debug/glibc/csu/ 中的0x7f08c84fe349。/csu/libc-start.c:381:3 #6 _start /build/glibc/src/glibc/csu/ 中的0x55a845337084。/sysdeps/x86_64/start。小号:115
答:
getline
当最长行的长度未知时很有用。它将根据需要分配内存。它还返回已处理的字符数。
最好重新分配给临时指针。如果失败,则原始指针仍然有效。realloc
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ( void) {
char *line;
size_t size = 0;
ssize_t length = 0;
int item = 0;
char** data = NULL;
for ( ; ; ) {
printf ( "Enter string %d: ", item + 1);
fflush ( stdout);
if ( 0 > ( length = getline ( &line, &size, stdin))) {
break;
}
char **temp = NULL;
if ( NULL == ( temp = realloc ( data, sizeof *data * (item + 1)))) {
fprintf ( stderr, "realloc problem\n");
break;
}
data = temp;
if ( NULL == ( data[item] = malloc ( sizeof **data * ( length + 1)))) {
fprintf ( stderr, "malloc problem\n");
break;
}
strcpy ( data[item], line);
item++;
}
free ( line);
printf("\n\nElements:\n");
for(int j = 0; j < item; j++) {
if ( data[j] && data[j][0]) { // not NULL and not zero
printf ( "%s", data[j]);
}
free(data[j]);
}
free(data);
return 0;
}
评论
data[item] = malloc(sizeof(char) * ( strlen(line) + 1));
memcpy()
strcpy()