2016-09-22 2 views
0

Je travaille avec des processus parallèles, et dans une partie de mon code, je veux lancer un nouveau processus qui appelle le même programme avec des arguments légèrement différents. Par exemple, si l'utilisateur s'appelait initialement "./prog arg1 arg2 arg3", je voudrais forker un nouveau processus qui exécute "./prog -n 1 arg2 arg3" puis ce programme fork et exec "./prog - n 2 arg3. " La seule façon de le faire est d'utiliser execv(), mais je rencontre des problèmes car execv nécessite que le dernier élément du tableau argv [] qui lui est passé soit NULL. Ci-dessous est mon code, et je vais poster la sortie de valgrind ci-dessous.c: mettre l'élément de tableau malloc'd à NULL (écriture invalide)

 //fork an additional process: ./prog -n (i+1) args... 
     // could accomplish by execv("./prog", paramlist), where paramlist is 
     //  the same as -n (i+1) and then argv, skipping argv[1] 

     //create new paramlist 
     char **params = malloc(sizeof(char*) * argc + 2); 

     sprintf(numbuf, "%d", i+1); 

     //./prog -n (i+1) argv[2:argc-1] 
     params[0] = argv[0]; 
     params[1] = "-n"; 
     params[2] = numbuf; 
     for(int i = 2; i<argc; i++){ //skip argv[0] bc we already assigned it 
      params[i+1] = argv[i];  //skip argv[1] because we just worked on it 

     } 
     params[argc+1] = NULL;   //list must be null terminated 

     pid3 = fork(); 
     if(0 == pid3){ 
      execv("./prog", params); 
      exit(-1); 
     } //no waitpid here, because we'd like this process to continue on its own 

     params[argc+1] = "";   //avoid invalid free 
     free(params); 

Quand je lance ce code normalement, je reçois l'erreur suivante:

*** Error in `./prog': free(): invalid next size (fast): 0x0000000001ac3830 *** 

Valgrind me dit ceci:

==28067== Memcheck, a memory error detector 
==28067== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==28067== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info 
==28067== Command: ./prog ./photos/photo1.jpg 
==28067== 
=====Displaying photo 0 (be patient.. XQuartz sucks) 
Enter degrees to rotate image(0,90,180,270): 90 
Enter a caption > thumb 
==28067== Invalid write of size 8 
==28067== at 0x400C58: main (in /usr/prog) 
==28067== Address 0x51fa8d0 is 16 bytes inside a block of size 18 alloc'd 
==28067== at 0x4C2BBAD: malloc (vg_replace_malloc.c:299) 
==28067== by 0x400C05: main (in /usr/prog) 
==28067== 
==28067== Invalid write of size 8 
==28067== at 0x400CC3: main (in /usr/prog) 
==28067== Address 0x51fa8d8 is 6 bytes after a block of size 18 alloc'd 
==28067== at 0x4C2BBAD: malloc (vg_replace_malloc.c:299) 
==28067== by 0x400C05: main (in /usr/prog) 
==28067== 
==28067== Invalid write of size 8 
==28067== at 0x400D0E: main (in /usr/prog) 
==28067== Address 0x51fa8d8 is 6 bytes after a block of size 18 alloc'd 
==28067== at 0x4C2BBAD: malloc (vg_replace_malloc.c:299) 
==28067== by 0x400C05: main (in /usr/prog) 
==28067== 
==28071== Syscall param execve(argv) points to unaddressable byte(s) 
==28071== at 0x4F00CF7: execve (in /usr/lib64/libc-2.23.so) 
==28071== by 0x400CE8: main (in /usr/prog) 
==28071== Address 0x51fa8d2 is 0 bytes after a block of size 18 alloc'd 
==28071== at 0x4C2BBAD: malloc (vg_replace_malloc.c:299) 
==28071== by 0x400C05: main (in /usr/prog) 
==28071== 
==28067== 
==28067== HEAP SUMMARY: 
==28067==  in use at exit: 0 bytes in 0 blocks 
==28067== total heap usage: 5 allocs, 5 frees, 1,051,194 bytes allocated 
==28067== 
==28067== All heap blocks were freed -- no leaks are possible 
==28067== 
==28067== For counts of detected and suppressed errors, rerun with: -v 
==28067== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0) 

Fait intéressant, si je commente les « libres (params) 'line, alors j'obtiens un défaut de segmentation, se produisant sur la ligne avant,' params [argc + 1] = ""; ' . Pourquoi est-ce que cela pourrait être?

Répondre

2
char **params = malloc(sizeof(char*) * argc + 2); 

devrait être

char **params = malloc(sizeof(char*) * (argc + 2)); 
+0

Ah, oui. Une réponse si simple ... Merci beaucoup! – AndyW