C 函数中的旧大小无效
所以我有这个函数C 函数中的旧大小无效,c,input,realloc,C,Input,Realloc,所以我有这个函数 void getInput(char* input) { char buffer[BUFF_SIZE]; char *buff = buffer; size_t buffersize = 32; getline(&buff, &buffersize, stdin); buffer[strlen(buffer) - 1] = '\0'; strcpy(input, bu
void getInput(char* input) {
char buffer[BUFF_SIZE];
char *buff = buffer;
size_t buffersize = 32;
getline(&buff, &buffersize, stdin);
buffer[strlen(buffer) - 1] = '\0';
strcpy(input, buffer);
}
这个函数被传递一个变量,声明为char input[BUFF\u SIZE]
,BUFF\u SIZE被定义为\define BUFF\u SIZE 5000
无论如何,我的错误是,当我在gdb中调试它时,我得到了错误
“/dash”中的错误:realloc():无效的旧大小:0x00007ffdf5a6fab0***
在使用之后,我将从中获取此信息
#0 0x00002aaaaad05387 in raise () from /lib64/libc.so.6
#1 0x00002aaaaad06a78 in abort () from /lib64/libc.so.6
#2 0x00002aaaaad47ed7 in __libc_message () from /lib64/libc.so.6
#3 0x00002aaaaad4e3e4 in malloc_printerr () from /lib64/libc.so.6
#4 0x00002aaaaad537d1 in _int_realloc () from /lib64/libc.so.6
#5 0x00002aaaaad55c52 in realloc_hook_ini () from /lib64/libc.so.6
#6 0x00002aaaaad3e96b in getdelim () from /lib64/libc.so.6
#7 0x0000000000400f05 in getInput (input=0x7fffffffbae0 "") at dash.c:104
#8 0x0000000000400bbe in main (argc=1, argv=0x7fffffffe308) at dash.c:50
此时我完全不知所措,任何帮助都将不胜感激。问题是,您无法首先将未分配
malloc
的缓冲区传递到getline
:
或者,在调用之前,*lineptr可以包含指向malloc(3)分配的缓冲区*n字节大小的指针。如果缓冲区不够大,无法容纳该行,则getline()使用realloc(3)调整其大小,并根据需要更新*lineptr和*n
getline
认为缓冲区不够大,因为传递的大小是32,所以它进入realloc
并失败,因为当系统在未分配的buffer
上调用realloc
时,它会调用未定义的行为(可能会使应用程序崩溃)
如果size\u t buffersize=5000,这个bug就会被隐藏设置了code>,因为getline
不必重新分配缓冲区(但如果一行大于5000个字符,则仍然是一个错误)
因此,您必须将buffer
设置为NULL
,并让getline
为您分配它
char *buff = NULL;
size_t buffersize = 0;
最后,取消分配free(buffer)
问题在于,您无法首先将未分配malloc
的缓冲区传递到getline
:
或者,在调用之前,*lineptr可以包含指向malloc(3)分配的缓冲区*n字节大小的指针。如果缓冲区不够大,无法容纳该行,则getline()使用realloc(3)调整其大小,并根据需要更新*lineptr和*n
getline
认为缓冲区不够大,因为传递的大小是32,所以它进入realloc
并失败,因为当系统在未分配的buffer
上调用realloc
时,它会调用未定义的行为(可能会使应用程序崩溃)
如果size\u t buffersize=5000,这个bug就会被隐藏设置了code>,因为getline
不必重新分配缓冲区(但如果一行大于5000个字符,则仍然是一个错误)
因此,您必须将buffer
设置为NULL
,并让getline
为您分配它
char *buff = NULL;
size_t buffersize = 0;
最后,取消分配free(buffer)
指向getline()
的指针(指向指针)参数必须可以传递到free()
。的POSIX规范说明:
应用程序应确保*lineptr
是可以传递给free()
函数的有效参数。如果*n
为非零,应用程序应确保*lineptr
指向大小至少为*n
字节的对象,或为空指针
您违反了该限制,因为无法将局部变量buffer
传递到free()
。所有的地狱都可能爆发——特别是当你还谎称缓冲区的大小时,声称它只有32字节长,而实际上它有5000字节长(因此对于很短的输入行,需要重新分配)
阅读说明书-遵循说明书中规定的规则
getInput()
函数也不知道函数的input
参数所指向的缓冲区大小,但它会无条件复制读入input
缓冲区的所有内容。这是造成缓冲区溢出的原因。您的getInput()
函数需要一个不同的签名,应该更像:
ssize_t getInput(size_t in_len, char input[in_len])
{
char *buffer = NULL;
size_t *buflen = 0;
ssize_t nbytes;
if ((nbytes = getline(&buffer, &buflen, stdin)) == -1)
{
free(buffer); // Free any space allocated by getline()
return EOF;
}
if (buffer[nbytes - 1] == '\n'). /* Zap newline if present */
buffer[--nbytes] = '\0';
if ((size_t)nbytes >= in_len)
{
free(buffer); // Release space allocated by getline()
*input = '\0';
return 0; // Or another value to indicate an error
}
strcpy(input, buffer);
free(buffer);
return nbytes;
}
这将告诉您输入缓冲区中有多少字节,从而避免溢出。它确实会复制数据,就像您的原始函数一样——据推测,这对您来说是可以的
请注意,getline()
返回-1
,而不是EOF
(尽管两者通常相同)。它可以(而且通常是这样)在检测EOF之前为空缓冲区指针分配空间,因此即使没有数据,也有必要释放它分配的缓冲区。getline()
的有效实现从不返回0
-它返回-1
或严格的正值。getline()
的指针(指向指针)参数必须可以传递到free()
。的POSIX规范说明:
应用程序应确保*lineptr
是可以传递给free()
函数的有效参数。如果*n
为非零,应用程序应确保*lineptr
指向大小至少为*n
字节的对象,或为空指针
您违反了该限制,因为无法将局部变量buffer
传递到free()
。所有的地狱都可能爆发——特别是当你还谎称缓冲区的大小时,声称它只有32字节长,而实际上它有5000字节长(因此对于很短的输入行,需要重新分配)
阅读说明书-遵循说明书中规定的规则
getInput()
函数也不知道函数的input
参数所指向的缓冲区大小,但它会无条件复制读入input
缓冲区的所有内容。这是造成缓冲区溢出的原因。您的getInput()
函数需要一个不同的签名,应该更像:
ssize_t getInput(size_t in_len, char input[in_len])
{
char *buffer = NULL;
size_t *buflen = 0;
ssize_t nbytes;
if ((nbytes = getline(&buffer, &buflen, stdin)) == -1)
{
free(buffer); // Free any space allocated by getline()
return EOF;
}
if (buffer[nbytes - 1] == '\n'). /* Zap newline if present */
buffer[--nbytes] = '\0';
if ((size_t)nbytes >= in_len)
{
free(buffer); // Release space allocated by getline()
*input = '\0';
return 0; // Or another value to indicate an error
}
strcpy(input, buffer);
free(buffer);
return nbytes;
}
这将告诉您输入缓冲区中有多少字节,从而避免溢出。