为什么我可以使用指针作为 write() 的缓冲区,但需要使用指针地址作为 read() 的缓冲区?

发布于 2024-10-19 10:12:04 字数 766 浏览 4 评论 0原文

我正在尝试将单个字符从父进程传输到子进程。通常这是通过一个简单的变量来完成的,但我正在用一个指针来尝试它。如果使用简单变量 (var) 完成,则 write() 和 read() 的缓冲区参数都是 &var,但是当我使用指针 (>*ptr),read() 的参数是 ptr,write() 的参数是 &ptr

我是 C 语言新手,我不太明白为什么会出现这种情况。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void) {

  char *chPtr;
  int fd[2];
  pid_t pid;

  char value = 'z';

  pipe(fd);
  pid = fork();

  if (pid) {     // Parent
    close(fd[0]);
    chPtr = &value;
    write(fd[1], chPtr, 1);
    close(fd[1]);
  }

  if (! pid) {   // Child
    close(fd[1]);
    read(fd[0], &chPtr, 1);
    printf("the result is %c\n", (int)chPtr);
    close(fd[0]);
  }
  return 0;
}

I'm trying to pipe a single character from a parent process to a child process. Usually this is done with a simple variable but I'm trying it out with a pointer. If it's done with a simple variable (var) the buffer argument for both write() and read() is &var, but when I use a pointer (*ptr), the argument for read() is ptr and the argument for write() is &ptr.

I'm new to C and I can't quite wrap my head around why this is the case.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void) {

  char *chPtr;
  int fd[2];
  pid_t pid;

  char value = 'z';

  pipe(fd);
  pid = fork();

  if (pid) {     // Parent
    close(fd[0]);
    chPtr = &value;
    write(fd[1], chPtr, 1);
    close(fd[1]);
  }

  if (! pid) {   // Child
    close(fd[1]);
    read(fd[0], &chPtr, 1);
    printf("the result is %c\n", (int)chPtr);
    close(fd[0]);
  }
  return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情话墙 2024-10-26 10:12:04

您的子实现没有按照您的预期进行。虽然它有效,但这确实是一个设计错误。

read() 函数读取调用者分配的缓冲区。因为您将 &chPtr 传递给 read(),所以您正在使用指针的内存作为缓冲区,这恰好可以工作,因为您只读取单个字符,该字符适合指针的内存。

通常你会想要这样的东西:

if (! pid) {   // Child
    char buf[1];
    close(fd[1]);
    read(fd[0], buf, 1);
    printf("the result is %c\n", buf[0]);
    close(fd[0]);
}

Your child implementation is not doing what you expect. Although it works, it is really a design bug.

The read() function reads into a buffer allocated by the caller. Because you are passing &chPtr to read(), you are using the memory for the pointer as your buffer, which happens to work since you are only reading a single character, which fits into the memory for a pointer.

Normally you would want something like:

if (! pid) {   // Child
    char buf[1];
    close(fd[1]);
    read(fd[0], buf, 1);
    printf("the result is %c\n", buf[0]);
    close(fd[0]);
}
风蛊 2024-10-26 10:12:04

指针顾名思义,它指向一个内存位置。如果是read,则您将在指针中存储一个值,而不是将该值放置在它指向的位置。事实上,通过在指针上使用 & 运算符,您实际上是在创建一个指向指针的指针。这就是为什么需要显式转换才能使用 printf 中的值。

相反,您应该将指针设置为 value 的地址,然后像这样正常使用指针:

chPtr = &value;
read(fd[0], chPtr, 1);
printf("the result is %c\n", value);

更常见的是使用字节数组(即 char[])而不是指针,或者而是在堆上分配内存(请参阅 malloc)。

A pointer does what its name suggests, it points to a memory location. If the case of the read, you are storing a value in the pointer instead of placing the value in the location to which it points. In fact, by using the & operator on a pointer you are in fact creating a pointer to a pointer. That's why the explicit cast is required to use the value in a printf.

Instead, you should set the pointer to the address of value and then use the pointer normally like so:

chPtr = &value;
read(fd[0], chPtr, 1);
printf("the result is %c\n", value);

It is more common to use an array of bytes (i.e. char[]) instead of a pointer, or instead allocate memory on the heap (see malloc).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文