gpt4 book ai didi

c - strcat() 和 read() 如何处理 C 中的 '\0'

转载 作者:行者123 更新时间:2023-11-30 16:29:51 25 4
gpt4 key购买 nike

首先是我的整个代码:

 1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <unistd.h>
4. #include <sys/wait.h>
5. #include <string.h>
6. int main(int argc, char *argv[]) {
7. int p[2]; // p[0]: file descriptor for read end of pipe
8. // p[1]: file descriptor for write end of pipe
9. if (pipe(p) < 0) exit(1);
10. int rc1 = fork();
11. if (rc1 < 0){ fprintf(stderr, "fork error\n"); }
12. else if (rc1 == 0){ write(p[1], "1st child output",
13. sizeof("1st child output")); }
14. else{
15. int rc2 = fork();
16. if (rc2 < 0){ fprintf(stderr, "fork error\n"); }
17. else if (rc2 == 0){
18. printf("2st child output\n");
19. char *_1st_child_out;
20. read(p[0], _1st_child_out, sizeof("1st child output"));
21. strcat(_1st_child_out, ", AFTER PIPE YA FOOL");
22. printf("%s\n", _1st_child_out);
23. }
24. }
25. }

如果我初始化 19:13:

char *_1st_child_out;

带有“\0”或 NULL,该字符串保持为空并且 22:13:

printf("%s\n", _1st_child_out);

不打印任何内容,那么 strcat() 和 read() 是如何工作的呢?在调用它们之前我不应该插入任何空终止符吗?垃圾值怎么样?

最佳答案

您的代码中几乎没有错误,这是我的观察结果。

情况 1 :- 在您的代码中,您正在调用 fork()两次,管道写入结束p[1]包含一些数据1st child output首先fork() rc1进程,但您的代码尝试读取表单 p[0]第二名rc2过程。

你应该检查read()返回值,无论是否成功,或者可能是从错误/未初始化的文件描述符中读取。这个

    char *_1st_child_out = NULL;
/* for process rc2, p[0] contains nothing, so what read() will read from p[0] ?? */
int ret = read(p[0], _1st_child_out, sizeof("1st child output"));
if(ret == -1) {
perror("read");
/* error handling */
}

自从数据写入 p[1]rc1进程,不在 rc2 中过程,但是当您尝试从 p[0] 读取时它给你

read: Bad address

情况 2:- 解决上述问题的一种方法是

int main(int argc, char *argv[]) {
int p[2]; // p[0]: file descriptor for read end of pipe
// p[1]: file descriptor for write end of pipe
if (pipe(p) < 0) exit(1);
int rc1 = fork();
if (rc1 < 0){ fprintf(stderr, "fork error\n"); }
else if (rc1 == 0){
write(p[1], "1st child output",sizeof("1st child output"));
}
else{
char *_1st_child_out = NULL;

/* read() will read from p[0] and store into _1st_child_out but _1st_child_out not holding any valid memory ? So it causes Undefined behavior */
int ret = read(p[0], _1st_child_out, sizeof("1st child output"));
if(ret == -1) {
perror("read");
/* error handling */
}
strcat(_1st_child_out, ", AFTER PIPE YA FOOL");
printf("%s\n", _1st_child_out);
}
return 0;
}

这里_1st_child_out是一个指针,并且指针应该具有有效的内存位置。您可以使用 NULL 进行初始化这是 (void*)0 ,这是有效的,但不适用于 \0因为它只是一个字符。

但是当你初始化_1st_child_out时与 NULL并从 p[0] 读取数据并存储到 _1st_child_out ,它会存储什么进去呢?它会导致段错误,并且也是未定义的行为

所以最好为 _1st_child_out 动态分配内存然后调用read()或创建堆栈分配数组,如

char _1st_child_out[10];

这是示例工作代码

int main(int argc, char *argv[]) {
int p[2]; // p[0]: file descriptor for read end of pipe
// p[1]: file descriptor for write end of pipe
if (pipe(p) < 0) exit(1);
int rc1 = fork();
if (rc1 < 0){ fprintf(stderr, "fork error\n"); }
else if (rc1 == 0){
write(p[1], "1st child output",sizeof("1st child output"));
}
else{

char *_1st_child_out = malloc(BYTE); /* define BYTE value as how much memory needed, and free the dynamically allocated memory once job is done */
int ret = read(p[0], _1st_child_out, sizeof("1st child output"));
if(ret == -1) {
perror("read");
/* error handling */
}
/* make sure _1st_child_out has enough memory space to concatenate */
strcat(_1st_child_out, ", AFTER PIPE YA FOOL");
printf("%s\n", _1st_child_out);
}
return 0;
}

注意:使用 strncat()而不是strcat() ,原因可以从strcat()的手册页找到https://linux.die.net/man/3/strcat它说

The strcat() function appends the src string to the dest string, overwriting the terminating null byte ('\0') at the end of dest, and then adds a terminating null byte. The strings may not overlap, and the dest string must have enough space for the result. If dest is not large enough, program behavior is unpredictable; buffer over‐ runs are a favorite avenue for attacking secure programs.

   The strncat() function is similar, except that

* it will use at most n bytes from src; and

* src does not need to be null-terminated if it contains n or more bytes.

As with `strcat()`, the resulting string in dest is always null-terminated.

关于c - strcat() 和 read() 如何处理 C 中的 '\0',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51576121/

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