对小文件使用读取时堆栈溢出的说明和有问题的解决方法
我希望这个问题能解释我的问题。如果能解释“有效”的解决方法,我也将不胜感激。
读取文件的传统方式(据我所知)
int fd;
char buffer[MAX];
while(read(fd,buffer,MAX)>0)
{
buffer[MAX]='\0';
write(sockfd,buffer,MAX);
memset(buffer,NULL,MAX);
}
会导致溢出。不知何故出乎意料地起作用的解决方法是
while((read(fd,buffer,MAX)!=0)||(read(fd,buffer,MAX)!= -1))
{
buffer[MAX]='\0';
write(sockfd,buffer,MAX);
memset(buffer,NULL,MAX);
}
^^ 此代码打印出整个文件,据观察没有跳过。
诸如此类的事情
do
{
int temp;
temp=read(fd,buffer,MAX);
if((temp == 0) || (temp == -1))
{
break;
}
buffer[MAX]='\0';
write(sockfd,buffer,MAX);
memset(buffer,NULL,MAX);
}while(1);
也导致了堆栈溢出。我在这里错过了一些真正重要的东西吗?
谢谢
I hope the question explained my problem. I would also be grateful if the workaround that "works" is explained.
The traditional way of reading a file (that i know of)
int fd;
char buffer[MAX];
while(read(fd,buffer,MAX)>0)
{
buffer[MAX]='\0';
write(sockfd,buffer,MAX);
memset(buffer,NULL,MAX);
}
was causing an overflow. The workaround that somehow unexpectedly worked was
while((read(fd,buffer,MAX)!=0)||(read(fd,buffer,MAX)!= -1))
{
buffer[MAX]='\0';
write(sockfd,buffer,MAX);
memset(buffer,NULL,MAX);
}
^^ This code printed out the entire file, no skips as far as observable.
Things like
do
{
int temp;
temp=read(fd,buffer,MAX);
if((temp == 0) || (temp == -1))
{
break;
}
buffer[MAX]='\0';
write(sockfd,buffer,MAX);
memset(buffer,NULL,MAX);
}while(1);
also caused a stack overflow. Am i missing something really important here?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
为什么说它会造成溢出呢?
请注意,
read()
不会在char
数组的末尾写入\0
,因此,如果您执行类似的操作, printf("%s", buffer)
它可能会失败,因为printf
将期待一个 NUL 终止的字符串。您可能想要读取MAX-1
并设置buffer[number_of_read_characters] = '\0'
,其中 number_of_read_characters 是read( )
返回,如果是肯定的。另请注意,当您声明
char buffer[MAX]
时,由于 C 索引是从零开始的,因此最高buffer
索引为MAX-1
,因此当您设置buffer[MAX]='\0'
时,您已经超出了数组范围。Why do you say that it's causing an overflow?
Do note that
read()
will not write a\0
in the end of thechar
array, so if you do something likeprintf("%s", buffer)
it will likely fail becauseprintf
will be expecting a NUL terminated string. You may be wanting to readMAX-1
and setbuffer[number_of_read_characters] = '\0'
where number_of_read_characters is whateverread()
returned, if positive.Also note that when you declare
char buffer[MAX]
, since in C indexing is zero-based, the highestbuffer
index isMAX-1
, so when you're settingbuffer[MAX]='\0'
you're already out of your array bounds.一个问题:
在堆栈上执行步骤,因为大小为 MAX 的数组的最高有效索引是 MAX-1(由于基于 0 的索引)。
read 的返回值 -1 表示错误,因此测试 read() > 的正确方法是: 0。此外,read 的正常返回值是读取的字节数,并且 read 不保证任何 0 终止。你必须按照以下方式做一些事情
One problem:
steps on stack, as the highest valid index for array of size MAX is MAX-1 (due to 0-based indexes).
-1 return value from read indicates an error, so the right thing to test read() > 0. Moreover, the normal return value from read is the number of bytes read, and read does not guarantee any 0-termination. you have to do someting along the lines of
看了一眼代码,我认为这是因为逻辑不同。
在有效的示例中,read(fd,buffer,MAX) 方法被执行两次。
可以这样想:
如果 dosomething() 方法是幂等的,则该循环将是无限的,但是如果第一次在 while 语句中运行它与第二次不同,它将中断。
这解释了执行路径的不同之处,但我无法弄清楚为什么第一个选项会溢出......我会考虑并更新。 (或者没有 - 似乎已经得到了回答!)
Glancing at the code, I'd suggest that it's because the logic is different.
In the example that works, the
read(fd,buffer,MAX)
method is being executed twice.Think of it like:
This loop will be infinite if the dosomething() method is idempotent, however if the first time you run it within the while statement is different than the second, it will break.
That explains how the execution path differs, but I can't figure out why the first option overflows... I'll think about it and update. (or not - it seems it's been answered!)
试试这个:
Try this: