我有一個簡單的代碼,假設在 Linux C 中讀取長度大小并從字符設備獲取資料。
這是我的代碼,errno 設定為 9。我確保檔案存在并且確實存在。并且能夠讀取它,cat /dev/mychardev-0但為什么在讀取時出現錯誤的檔案描述符錯誤。我讓這條線通過了int fd=open("/dev/mychardev-0",O_RDONLY); if(fd<0)
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
int main()
{
int fd=open("/dev/mychardev-0",O_RDONLY);
if(fd<0)
{
printf("fd %d\n",fd);
exit(0);
}
int length=1024000;
int x=0;
char buffer[length-1];
while(x<length)
{
int valread=read(fd,&buffer[x],length);
if(valread==0)
{
printf("zero bytes read\n");
break;
}
if(valread<0)
{
printf("read return negative %d %d\n",valread,errno);
break;
}
x=x valread;
}
if(x>0)
{
printf("%x",buffer);
}
else
{
printf("ops no read\n");
}
return 0;
}
uj5u.com熱心網友回復:
char buffer[length-1];
int valread=read(fd,&buffer[x],length);
這是一個非常糟糕的主意。您為位元組分配足夠的空間,length - 1然后嘗試將length位元組讀入該空間。
如果讀取獲得最大可能大小,您將有緩沖區溢位,進入未定義的行為區域(1)。
而且,最重要的是,您嘗試讀取length位元組,即使您可能已經在回圈的早期迭代中讀取了一些位元組。你應該:
- 使用正確的緩沖區長度;和
- 根據您已經閱讀的內容調整長度。
而且,雖然這可能不是問題,但 1 meg 是要放入堆疊的大量資料(默認情況下通常限制大小)。如果是這種情況,您可能最好使用malloc獲取動態緩沖區,例如:
char *buffer = malloc(length);
// make sure buffer != NULL, then use it.
free(buffer);
所以,像(未經測驗,但你應該希望得到這個想法):
int x = 0, length = 1024000; // with malloc if needed.
char buffer[length];
while (x < length) {
int valread = read(fd, &buffer[x], length - x);
if (valread == 0) {
printf("zero bytes read\n");
break;
}
else if (valread < 0) {
printf("read return negative %d %d\n",valread,errno);
break;
}
x = valread;
}
(1)可能發生的一個例子是緩沖區溢位會以某種方式影響堆疊上的其他變數。
例如,它可能會損壞x,這意味著您的下一次讀取可能會轉到記憶體中的某個任意位置,結果可能會損壞其他東西。
Or it could corrupt fd which would make the next read likely to fail with an invalid file descriptor.You can check the actual behaviour by simply printing out those two values before any use. Given the fact you mention "bad file descriptor error", that's possibly the most likely scenario here.
But, to be honest, the best solution is probably just to avoid undefined behaviour (though it may still be educational for you to find out the effects).
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/440248.html
