2010-12-09 61 views
2

J'ai donc une fonction qui charge une variable char ** avec quelques données de chaîne. Mon but est de fourchonner le processus et d'imprimer certaines de ces données dans l'enfant, et d'autres dans le parent. Cependant, je suis incapable de référencer le pointeur après l'appel fork().Référence des pointeurs après un appel de fork() C

Je pensais que fork() a fait une copie de l'espace d'adressage ensemble du processus parent, ce qui semble qu'il comprendrait les différents pointeurs de pile ...

Essentiellement, mon code ressemble actuellement à ceci:

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! */ 

Quelqu'un at-il une idée de ce que je fais de mal? J'ai fait un peu de recherche sur google à ce sujet, et il semble que ce que je fais devrait fonctionner - mais ce n'est pas le cas. Ainsi, je suis malentendu quelque chose de fondamental ...

+0

* "Je pensais que fork() fait une copie de tout l'espace d'adressage du processus parent, ce qui semble inclure les différents pointeurs de pile ... "* Ceci n'est pas pertinent pour la question, mais au moins sur la plupart des systèmes UNIX modernes,' fork' doesn ' t copier tout l'espace d'adresse au moment où il est appelé. Il utilise un schéma * copy-on-write *; les pages de mémoire sont copiées dès qu'elles changent. Il * sent * comme des pages de mémoire copiées au moment de 'fork '. –

Répondre

3

que vous faites des opérations mauvais pointeur et juste obtenir la chance sur le premier appel - voici ce que le code devrait ressembler à:

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

Il devrait être 'NULL' tout en majuscule, d'ailleurs. –

+0

Cela suppose que la fonction OP serait 'load_data (char * &)' en C++. Ce qui serait probablement le cas, et l'utilisation de l'OP est certainement fausse, mais il y a une chance que l'OP ait besoin d'un «char **». –

+0

J'ai en fait besoin de char **, car je travaille autour d'un code existant et la fonction load_data est déjà écrite pour moi en prenant le caractère **. Dans mon cas d'utilisation actuel, les données sont en fait un argument argv **, que je transmettrai à argv [0] à un appel execve. Des conseils pour faire ce travail dans ce cas? – camperdave

1

Dans votre cas, data ne pointe nulle part. L'utilisation d'une variable non initialisée est un comportement indéfini. Même s'il a changé dans la fonction load_data, le changement ne sera pas visible à l'extérieur.

Vous devez soit faire le point data à quelque chose valide, ou de transmettre l'adresse de data à la fonction pour que les modifications « retour », comme dans load_data(char ***data).


Votre code, avec un minimum de changements pour en faire un programme complet, "travaille" pour moi

#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; 
} 

Et une course exemple

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

Votre code fonctionne bien sur mon système, mais je ne peux pas utiliser de mémoire dynamique dans ce cas. Je ne suis pas sûr de ce qui est différent entre mon code actuel et le vôtre, à part ça ... ce qui fait partie de la raison pour laquelle je suis si confus. – camperdave

+0

Votre 'data' n'est pas initialisé. Voir mes nouveaux commentaires en haut de ma réponse. – pmg