Ссылки на указатели после вызова fork () в C - PullRequest
2 голосов
/ 09 декабря 2010

Итак, у меня есть функция, которая загружает переменную char ** с некоторыми строковыми данными. Моя цель состоит в том, чтобы обработать процесс и распечатать некоторые из этих данных в дочернем элементе, а некоторые из родительского. Однако я не могу ссылаться на указатель после вызова fork ().

Я думал, что fork () сделал копию всего адресного пространства родительского процесса, который, похоже, будет включать в себя различные указатели стека ...

По сути, мой код в настоящее время выглядит так:

load_data(char **data);

char** data;
load_data(data);
printf("String 0: %s\n", data[0]);
fork(); 
printf("String 0 again: %s\n", data[0]);    /* Segfaults Here! */

У кого-нибудь есть идеи, что я делаю не так? Я провел небольшой поиск в Google по этому вопросу, и кажется, что я делаю, должно работать - но это не так. Таким образом, я неправильно понимаю нечто фундаментальное ...

Ответы [ 2 ]

4 голосов
/ 09 декабря 2010

Вы делаете плохие операции с указателями и просто везете при первом вызове - вот как должен выглядеть код:

load_data(char **data);

char* data = NULL;
load_data(&data);
printf("String 0: %s\n", data);
fork(); 
printf("String 0 again: %s\n", data);    /* Doesn't Segfault Here! */
1 голос
/ 09 декабря 2010

В вашем случае, data никуда не указывает. Использование неинициализированной переменной - неопределенное поведение. Даже если оно изменилось внутри функции load_data, изменение не было бы видно снаружи.

Вам нужно либо заставить data указать на что-то допустимоеили передать адрес data в функцию, чтобы изменения «return», как в load_data(char ***data).


Ваш код, с минимальными изменениями, чтобы сделать его полной программой, «работает»"для меня

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

int load_data(char **data);

int main(void) {
  char **data;
  data = malloc(2 * sizeof *data);
  assert(data && "no memory");
  load_data(data);
  printf("String 0: %s\n", data[0]);
  fork();
  printf("String 0 again: %s\n", data[0]);
  return 0;
}

int load_data(char **data) {
  data[0] = "one";
  data[1] = "two";
  return 2;
}

и пример прогона

$ ./a.out 
String 0: one
String 0 again: one
String 0 again: one
...