C 额外的memset()会导致系统调用open()失败

C 额外的memset()会导致系统调用open()失败,c,linux,kernel,system-calls,memset,C,Linux,Kernel,System Calls,Memset,我已经按照教程在/dev中创建了一个节点,我尝试使用以下代码访问/dev/chardev中的设备: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> //perror(), errno #include <string.h> #define RSIZE 50 int main() { int fd,err_save;

我已经按照教程在/dev中创建了一个节点,我尝试使用以下代码访问/dev/chardev中的设备:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h> //perror(), errno
#include <string.h>
#define RSIZE 50 

int main()
{
    int fd,err_save;
    char receive_buff[RSIZE];

    //open device and check for error msg
    fd = open("/dev/chardev", "rw");
    err_save = errno;
    if (fd < 0)
        {
        perror("open perror");
        printf("error opening device, fd = %d, err_save = %d \n", fd,err_save);
        }
    else
        {printf("Device opened\n");}

    //read device and check for error msg
    //memset(receive_buff, 0, sizeof(receive_buff)); //<--- strange
    read(fd, receive_buff, RSIZE);
    err_save = errno;
        if (fd < 0)
        {
        perror("read perror");
        printf("error reading device, fd = %d, err_save = %d \n", fd,err_save);
        }
    else
        {
        printf("Device read successful : %s\n",receive_buff);}

    //close device and check for error msg
    fd = close(fd);
    err_save = errno;
    if (fd < 0)
        {
        perror("close perror");
        printf("error closing device, fd = %d, err_save = %d \n", fd,err_save);
        }
    else
        {printf("Device closed\n");}
    return 0;
}    
但是,当memsetreceive_buff为0时,sizeofreceive_buff;如果没有注释,我会得到以下信息:

open perror: File exists
error opening device, fd = -1, err_save = 17 
read perror: Bad file descriptor
error reading device, fd = -1, err_save = 9 
close perror: Bad file descriptor
error closing device, fd = -1, err_save = 9 
问题:额外的memset是如何导致open失败的?

open将整数作为第二个参数,您会将其与fopen混淆。您的开放线路应为:

fd = open("/dev/chardev", O_RDWR);
fd = open ("/dev/chardev", O_RDWR);

它在添加和删除代码时工作或失败的原因与不可预测的rw地址值有关,在删除memset时,rw可能恰好是open的有效值。

您需要在open的第二个参数中传递一个整数,在您的情况下,它是O_RDWR。电话应为:

fd = open("/dev/chardev", O_RDWR);
fd = open ("/dev/chardev", O_RDWR);
阅读手册:手动2打开。链接:

更新

您错误地检查了读取错误。您的代码:

read(fd, receive_buff, RSIZE);
err_save = errno;
if (fd < 0)
{
  perror("read perror");
  printf("error reading device, fd = %d, err_save = %d \n", fd,err_save);
}
您的代码运行正常,因为第二个参数只是一个设置了位值的整数,具有特定的解释。传递一个地址,即加载的可执行文件中字符串的基址,它也是一个整数,有一些特定的字段设置和一些未设置的字段。无法判断这些位是通过对标志进行正确的ORing设置的,还是碰巧设置了特定位的随机整数。因此,该函数将通过检查是否设置了位来解释随机整数,并根据分配给每个位的解释工作


此外,在读取文件时,不检查读取是否成功。如果随机整数恰好有正确的位用于读取文件集,那么它将正确读取。

编译器没有警告您它应该做的事情,或者您忽略了它确实给您的警告

其他人已经告诉过你open的第二个参数是int;传递字符串文字是不正确的

open2手册页指出,您需要:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
您的编译器至少应该警告您,open函数没有可见的声明。嗯,我刚查过;我很失望地看到gcc在默认情况下没有做到这一点。在C99中,调用没有可见声明的函数是一种违反约束的行为,但大多数编译器默认情况下不支持C99(如果有的话)


您可能正在使用gcc。启用更多以-Wall-Wextra开头的警告,并注意编译器告诉您的内容。阅读手册页上的任何函数,看看需要哪些标题。

在我做了更改后,它起了作用,我写了rw,但没有意识到。。谢谢