2010-08-17 6 views
3

J'appelle une fonction qui branche et exécute le code d'un autre processus pour moi. Il y a plusieurs processus, étiquetés B, C et D. J'ai un code presque identique pour créer les différents processus. Pour une raison bizarre que je ne peux pas découvrir, une des fonctions de création de processus provoque une erreur de segmentation. Ils me semblent identiques. Y a-t-il une chance que quelqu'un puisse peser, peut-être me donner un aperçu de ce qu'est le problème?Strange sprintf erreur dans C

void spawn_process_b(int fileID[]){ 
    int pid; 
    char * argv[2]; 

    sprintf(argv[0], "%d", fileID[0]); 
    sprintf(argv[1], "%d", fileID[1]); 

    pid = fork(); 

    if (pid == 0) 
    { 
     execv("PipeW1", argv); 
    } 
} 

void spawn_process_c(int fileID[]){ 
    int pid; 
    char * argv[2]; 

    sprintf(argv[0], "%d", fileID[0]); 
    sprintf(argv[1], "%d", fileID[1]); 

    pid = fork(); 

    if (pid == 0) 
    { 
     execv("PipeW2", argv); 
    } 
} 

Grâce à la mise en points d'arrêt avec Cout < < "BP1" < < endl; et ainsi de suite, j'ai découvert que spawn_process_b s'exécutera très bien. spawn_process_c entrera, mais obtiendra un segfault lors de la première instruction de sprint. Quelqu'un a des idées? A l'origine, spawn_process_b me donnait des problèmes, et ... ma main à Dieu ... Je n'ai rien changé, et ça a commencé à fonctionner. Je me demande presque si c'est quelque chose qui pourrait dépendre de l'environnement?

Répondre

9

argv[0] est un pointeur non défini sur aucune zone de stockage allouée lorsque vous y entrez sprintf. Quand cela a fonctionné, c'était par accident, avec la mémoire que vous avez gribouillée juste pour être dans votre espace de processus.

La déclaration auto de argv vous permet d'attribuer de l'espace pour deux pointeurs char *. Les pointeurs sont probablement remplis de courrier indésirable (c'est-à-dire, ils pointent vers des emplacements aléatoires) et il n'y a pas d'espace alloué pour y stocker des caractères.

Vous avez besoin quelque chose comme

char *argv[3]; 
for (int i = 0; i < 2; i++) 
    argv[i] = malloc(space enough for my integer); 
argv[2] = 0; 

Si cette dernière ligne est assez important pour execv

+0

Pourquoi cela fonctionnerait-il dans spawn_process_b? Et cela fonctionne vraiment ... le processus supplémentaire appelé affichera des résultats à l'écran qui prouvent qu'il obtient les valeurs. – rybosome

+0

Ceci s'applique aux deux segments de code. 'char * argv [2]' alloue un tableau de deux pointeurs, mais n'initialise aucun pointeur. – Thanatos

+0

@Ryan: Vous êtes chanceux. C'est un comportement indéfini - il pourrait fonctionner, il pourrait ne pas fonctionner, selon l'état actuel de la mémoire. – Thanatos

4

Vous avez été chanceux que l'une des fonctions effectivement travaillées. Ce que vous faites est un comportement indéfini dans les deux cas, car vous n'avez pas alloué de mémoire pour les chaînes dans lesquelles vous imprimez. Déclare seulement un tableau de 2 pointeurs de caractères, mais ils ne pointent nulle part.

char *argv[2] Vous devez allouer de la mémoire pour eux avant de pouvoir les utiliser, que ce soit statiquement comme ceci:

char argv[2][100]; // 2 strings of 100 characters each 

ou dynamique comme ceci:

char *argv[2]; 
int i; 
for (i = 0; i < 2; i++) 
    argv[i] = (char *)malloc(100 * sizeof(char)); // 100 characters 
1

Votre argv[0] et argv[1] pointeurs ombles doivent pointer vers quelque chose et être initialisé.