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

时间:2011-02-25 04:23:40

标签: c pointers pipe

我正在尝试将父进程中的单个字符传递给子进程。通常这是通过一个简单的变量来完成的,但我正在尝试使用指针。如果使用简单变量(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;
}

2 个答案:

答案 0 :(得分:1)

您的孩子实施不符合您的期望。虽然它有效,但它确实是一个设计错误。

read()函数读入调用者分配的缓冲区。因为你正在将&amp; 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]);
}

答案 1 :(得分:1)

指针执行其名称所暗示的内容,它指向内存位置。如果是read的情况,则在指针中存储值而不是将值放在它指向的位置。实际上,通过在指针上使用&运算符,您实际上是在创建指针的指针。这就是为什么需要使用显式强制转换来使用printf中的值。

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

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

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