C 使用read()和write()的分段错误(堆芯转储)
我已经退出C语言编程将近两年了,最近在学校得到了一个关于使用write()和read()的作业 在代码的某个地方,我收到了分段错误,可能是在filecopy函数上,这是我投入资金的地方。我试过GDB,但自从上次用C编程以来我就没用过它,所以我转到这里 密码C 使用read()和write()的分段错误(堆芯转储),c,C,我已经退出C语言编程将近两年了,最近在学校得到了一个关于使用write()和read()的作业 在代码的某个地方,我收到了分段错误,可能是在filecopy函数上,这是我投入资金的地方。我试过GDB,但自从上次用C编程以来我就没用过它,所以我转到这里 密码 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <fc
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
void filecopy(int infd, int outfd);
int fd = -1;
char *prog = argv[0];
if(argc == 1)
filecopy(STDIN_FILENO, STDOUT_FILENO);
else
while(--argc > 0) {
if((fd = open(*++argv, O_RDONLY, "rb")) == -1) {
// we don't have fprintf... but we have sprintf =]
char tmp[30];
sprintf(tmp, "%s: can't open %s\0", prog, *argv);
write(STDOUT_FILENO, &tmp, sizeof(tmp));
exit(-1);
} else {
filecopy(fd, STDOUT_FILENO);
close(fd);
}
}
exit(0);
}
void filecopy(int infd, int outfd) {
// char *buf[1]; <-- causes unreadable characters outputted by write
char *buf;
while(read(infd, buf, 1) != -1)
write(outfd, buf, sizeof(buf));
}
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[]){
无效文件副本(输入、输出);
int-fd=-1;
char*prog=argv[0];
如果(argc==1)
文件副本(标准文件号、标准文件号);
其他的
而(--argc>0){
如果((fd=open(*++argv,orduonly,“rb”))=-1){
//我们没有fprintf…但是我们有sprintf=]
char-tmp[30];
sprintf(tmp,“%s:无法打开%s\0”,prog,*argv);
写入(STDOUT_FILENO,&tmp,sizeof(tmp));
出口(-1);
}否则{
文件副本(fd、STDOU文件号);
关闭(fd);
}
}
出口(0);
}
无效文件副本(int infd,int outfd){
//char*buf[1];char*buf;
是一个未初始化的指针,通过该指针写入数据是无效的
未定义的行为
char buf[1024];
ssize_t len;
while((len = read(infd, buf, sizeof buf)) != -1)
write(outfd, buf, len);
这是正确的
请注意,char*buf[1];
是指针的数组(维度为1),即
与char
s数组不同。使用该数组需要执行以下操作
read(infd,buf[0],somelength)
,但这里的buf[0]
将是一个
如果指针未初始化,您也会遇到同样的问题。这就是为什么要声明
例如1024的char
数组(您可以选择其他大小)是正确的
去做
也主要用于strlen(tmp)
和非sizeof(tmp)
strlen
返回字符串的长度,该长度可能小于29,并且
如果使用sizeof(tmp)
,则可能会在结束后写入垃圾
请注意,对于整个字符串,0可能太小,我会使用
较大的数字或使用snprintf
构造字符串:
snprintf(tmp, sizeof tmp, "%s: can't open %s\0", prog, *argv);
这样会更安全
最后一件事:
while(--argc > 0)
if((fd = open(*++argv, O_RDONLY, "rb")) == -1) {
...
虽然这是正确的,但我觉得这段代码很难理解
如果您这样做,阅读起来就会简单得多:
for(int i = 1; i < argc; ++i)
if((fd = open(argv[i], O_RDONLY, "rb")) == -1) {
...
[……]
mode参数指定创建新文件时应用的文件模式位。必须在
O_create
或O_TMPFILE
在标志中指定;如果既不指定O_create
也不指定O_TMPFILE
,则忽略模式。
有效模式由进程的umask
以通常方式修改:在没有默认ACL
的情况下,创建文件的模式为
(mode&~umask)
。请注意,此模式仅适用于将来访问新创建的文件;创建
只读文件可能会返回一个读/写文件描述符
为模式提供以下符号常量:
S_IRWXU
00700
用户(文件所有者)具有读取、写入和执行权限
S\u IRUSR
00400
用户具有读取权限
S_IWUSR
00200
用户具有写入权限
S_IXUSR
00100
用户具有执行权限
[……]
由于您既不使用O_create
也不使用O_TMPFILE
,因此此参数将
忽略并将char*
作为mode\u t
传递,该模式本质上是整数。
因此,您的电话应该是:
if((fd = open(argv[i], O_RDONLY, 0)) == -1) {
...
char*buf;
是未初始化的指针,通过该指针写入数据是无效的
未定义的行为
char buf[1024];
ssize_t len;
while((len = read(infd, buf, sizeof buf)) != -1)
write(outfd, buf, len);
这是正确的
请注意,char*buf[1];
是指针的数组(维度为1),即
与char
s数组不同。使用该数组需要执行以下操作
read(infd,buf[0],somelength)
,但这里的buf[0]
将是一个
如果指针未初始化,您也会遇到同样的问题。这就是为什么要声明
例如1024的char
数组(您可以选择其他大小)是正确的
去做
也主要用于strlen(tmp)
和非sizeof(tmp)
strlen
返回字符串的长度,该长度可能小于29,并且
如果使用sizeof(tmp)
,则可能会在结束后写入垃圾
请注意,对于整个字符串,0可能太小,我会使用
较大的数字或使用snprintf
构造字符串:
snprintf(tmp, sizeof tmp, "%s: can't open %s\0", prog, *argv);
这样会更安全
最后一件事:
while(--argc > 0)
if((fd = open(*++argv, O_RDONLY, "rb")) == -1) {
...
虽然这是正确的,但我觉得这段代码很难理解
如果您这样做,阅读起来就会简单得多:
for(int i = 1; i < argc; ++i)
if((fd = open(argv[i], O_RDONLY, "rb")) == -1) {
...
[……]
mode参数指定创建新文件时应用的文件模式位。必须在
O_create
或O_TMPFILE
在标志中指定;如果既不指定O_create
也不指定O_TMPFILE
,则忽略模式。
有效模式由进程的umask
以通常方式修改:在没有默认ACL
的情况下,创建文件的模式为
(mode&~umask)
。请注意,此模式仅适用于将来访问新创建的文件;创建
只读文件可能会返回一个读/写文件描述符
为模式提供以下符号常量:
S_IRWXU
00700
用户(文件所有者)具有读取、写入和执行权限
S\u IRUSR
00400
用户具有读取权限
S_IWUSR
00200
用户具有写入权限
S_IXUSR
00100
us