gpt4 book ai didi

c - fscanf 导致段错误

转载 作者:太空宇宙 更新时间:2023-11-04 06:12:01 28 4
gpt4 key购买 nike

我正在编写一段代码,用于计算父进程为 init 的进程数。调用 fork 并让子进程使用 exec 函数并将其输出通过管道传回父进程。在那一端一切似乎都很好,但是当我在管道的父级读取端使用 fdopen,然后使用 fscanf 时,程序崩溃了,即使 FILE 流不是 NULL。我检查了每个函数调用。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>

static void fatalError(char *message);

int main(int argc, char *argv[])
{

int total, initCount = 0;
int pipeToParent[2];
pid_t pid;
FILE *file;



if (pipe(pipeToParent) < 0)
fatalError("pipe() error");

if ((pid = fork()) < 0)
fatalError("fork() error");
else if (pid == 0) {

if (close(pipeToParent[0]) < 0)
fatalError("close() error");

if (dup2(pipeToParent[1], STDOUT_FILENO) < 0)
fatalError("dup2() error");

execlp("ps", "ps", "ahxo", "ppid", NULL);
fatalError("exec() error");

}


if (close(pipeToParent[1]) < 0)
fatalError("close() error");

wait(NULL);

if ((file = fdopen(pipeToParent[0], "r")) == NULL)
fatalError("fdopen() error");


for (total = 0; fscanf(file, "%d", &pid) != EOF; total++)
if (pid == 1)
initCount++;

if (fclose(file) < 0)
fatalError("fclose() error");

printf("%.2f%%\n", (float) initCount * 100 / total);
exit(EXIT_SUCCESS);


}


static void fatalError(char *message) {
perror(message);
exit(EXIT_FAILURE);
}

运行 GDB 给出了这个:

Program received signal SIGSEGV, Segmentation fault.
__isoc99_fscanf (stream=0x55757260, format=0x555555554c44 "%d") at isoc99_fscanf.c:30
30 isoc99_fscanf.c: No such file or directory.

Makefile 警告:

gcc -std=c11 -g -Wall -pedantic    init.c   -o init
init.c: In function ‘main’:
init.c:55:14: warning: implicit declaration of function ‘fdopen’; did you mean ‘fopen’? [-Wimplicit-function-declaration]
if ((file = fdopen(pipeToParent[0], "r")) == NULL)
^~~~~~
fopen
init.c:55:12: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
if ((file = fdopen(pipeToParent[0], "r")) == NULL)
^

最佳答案

在 C 中,如果不存在先前的函数声明,则假定该函数返回一个 int。 .如果编译器假定函数返回 int当它返回 FILE *如果sizeof(FILE*) < sizeof(int)返回值被截断并且无效。因此,当指针传递给 fscanf 时,您会得到内部 glibc 错误。被截断且无效。

来自 man fdopen你可以阅读:

fdopen(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE

这些是您需要定义的宏以拥有 fdopen()在你的程序中声明。您需要在任何包含之前定义它们。我通常只定义 _GNU_SOURCE它定义了 _POSIX_C_SOURCEfeatures.h .

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>

.. rest of the program ...

有关详细信息,请参阅 future test macros .

使用 gcc 时你也可以做 gcc -std=gnu11或其他-std=gnu* . -std=c11-std=gnu11相同除了宏 _GNU_SOURCE编译时预定义。

关于c - fscanf 导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54207824/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com