如何解决功能中的旧尺寸无效
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_SIZE]
的变量,并且BUFF_SIZE被定义为#define BUFF_SIZE 5000
无论如何,我遇到的错误是当我在gdb中调试它时出现错误
Error in './dash': realloc(): invalid old size: 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
我现在完全迷失了,任何帮助将不胜感激。
解决方法
getline()
的指针(指向指针)参数必须可传递给free()
。 getline()
的POSIX规范说:
应用程序应确保
*lineptr
是可以传递给free()
函数的有效参数。如果*n
不为零,则应用程序应确保*lineptr
指向大小至少为*n
个字节的对象,或者为空指针。
您违反了该限制,因为无法将局部变量buffer
传递给free()
。一切都可能崩溃—尤其是因为您还担心缓冲区的大小,声称实际上只有5000字节长,所以缓冲区只有32字节长(因此,对于很短的输入行,必须重新分配)。
阅读规范-遵循制定的规则。
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之前,它可以(通常确实)为NULL缓冲区指针分配空间,因此即使没有数据,也必须释放它分配的缓冲区。有效的getline()
实现永远不会返回0
,它会返回-1
或严格为正的值。
问题在于,您不能将尚未分配给malloc
的缓冲区传递给getline
:
或者,在调用getline()之前,* lineptr可以包含一个指向malloc(3)分配的缓冲区的指针* n个字节。 如果缓冲区的大小不足以容纳该行,则getline()使用realloc(3)调整其大小,并根据需要更新* lineptr和* n。
getline
认为缓冲区不够大,因为传递的大小为32,所以它前进到realloc
并失败,因为当系统在非(m )分配的realloc
会调用未定义的行为(可能会使您的应用程序崩溃)。
如果设置了buffer
,该错误将被隐藏,因为size_t buffersize = 5000;
不必重新分配缓冲区(但是如果行大于5000个字符,这仍然很糟糕,所以它是还是一个错误)
因此,您必须将getline
设置为buffer
,并让NULL
为您分配它。
getline
最后,用char *buff = NULL;
size_t buffersize = 0;
取消分配
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。