【发布时间】:2015-07-17 08:42:31
【问题描述】:
这是我第一次在 C 语言中遇到分段错误 11,我似乎无法理解实际出了什么问题。
我想要做的是将一些 int 值写入一个结构加上来自子进程的命令行 (char *) 的文件名,然后将结构写入管道以从父进程读取.当它只有整数并且我取出使用字符串的代码时它工作正常,但是一旦我添加字符串并尝试在父进程中打印出文件名,我在程序运行时得到分段错误 11。
我查看了来自各地的各种帖子,但注意到常见的问题是当有人尝试将字符串分配给 char 数组并打印时,但我确保在这里只使用 char *。这是它锁定的代码
if((read(pd[0], &pv, 2048)) == -1)
{
error_exit("read not working");
}
printf("words = %d\n", pv.words);
printf("lines = %d\n", pv.lines);
printf("bytes = %d\n", pv.bytes);
printf("file = %s\n", pv.file); //locks up here and gives segmentation fault 11 on the command line
这是我运行程序时读出的程序:
$ ./a testfile
Parent process... should be waiting on child...
In child process! pid = 21993
it worked? testfile
Done with child process!
words = 1
lines = 2
bytes = 3
Segmentation fault: 11
这里还有完整的代码 编辑:我使用 sizeof 换出代码 for string 并使用 strlen
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
void error_exit(char *);
typedef struct total {
int words, lines, bytes;
char *file;
} Vals;
int main(int argc, char *argv[])
{
int pd[2]; //pipe descriptor
pid_t pid;
Vals v, pv;
char *fname = "Not set";
if(argc > 1)
{
fname = malloc(strlen(argv[1]));
strcpy(fname, argv[1]);
}
if((pipe(pd)) == -1)
{
error_exit("pipe creation");
}
if((pid = fork()) == -1)
{
error_exit("the fork forked up!");
}
else if(pid == 0)
{
printf("In child process! pid = %d\n", getpid());
v.words = 1;
v.lines = 2;
v.bytes = 3;
v.file = malloc(strlen(fname));
strcpy(v.file, fname);
printf("it worked? %s\n", v.file);
close(pd[0]);
if((write(pd[1], &v, sizeof(v.words) + sizeof(v.lines) + sizeof(v.bytes) + strlen(v.file))) == -1)
{
error_exit("Write from child");
}
//return; //return from child
printf("Done with child process!\n");
close(pd[1]);
return 0;
}
else
{
printf("Parent process... should be waiting on child...\n");
}
//wait for child
while((pid = wait(NULL)) > 0);
close(pd[1]);
//Vals pv = {0, 0, 0, "pv.file not set"};
//just assign anything to file to see if it fixes
//pv.file = malloc(strlen(fname));
if((read(pd[0], &pv, 2048)) == -1)
{
error_exit("read not working");
}
printf("words = %d\n", pv.words);
printf("lines = %d\n", pv.lines);
printf("bytes = %d\n", pv.bytes);
printf("file = %s\n", pv.file); //locks up here and gives segmentation fault 11 on the command line
close(pd[0]);
//program ended normally
return 0;
}
void error_exit(char *err)
{
printf("exiting because of this section: %s\nerrno = %d", err, errno);
exit(1);
}
我非常感谢对此的任何见解!
【问题讨论】:
-
我认为你想要
strlen(v.file)而不是sizeof(v.file)。 -
哦,是的,这让生活变得更轻松 :) 我在整个代码中都进行了更改,但仍然出现分段错误。我确实注意到,如果我做 pv.file = malloc(strlen(fname)); 在从管道读取父级之前那么它不会给我分段错误,但它会打印出一个空字符串。
-
另外,
sizeof(argv[1]),同样的问题。而fname = argv[1];也可能不会做你想做的事。试试strcpy。 -
不要通过管道发送指针;它们在其他虚拟地址空间上毫无用处
-
另外,为了方便调试,我会保存 write() 和 read() 的返回值(它们包含实际写入和读取的字节数)并打印出来,