2012-06-25 4 views
2

J'ai une question pour vous!Tableau dynamique 2D non initialisé - argument à fonction C

I ont un programme de C dans lequel i ont un tableau 2D dynamique dans ma fonction principale:

int **neighbours; 

qui i initialiser basé sur des arguments de ligne de commande. Le problème est que je veux nettoyer le code un peu. Pour ce faire, je veux créer une fonction dans un fichier d'en-tête qui prend le tableau non initialisé comme argument de référence et l'initialiser là.

Voilà comment j'appelle la fonction:

init(&nodeNum, &neighbours, argv[1], &nodes); 

c'est comment je déclare la fonction dans le fichier d'en-tête:

int init(int *nodeNum, int ***neighbours, char *arg, struct node **nodes) 

et voici comment essayer d'allouer la mémoire:

neighbours=malloc(*nodeNum*sizeof(int *)); 
     for(i=0;i<*nodeNum;i++){ 
      neighbours[i] = malloc(*nodeNum*sizeof(int *)); 
     } 

bien évidemment quelque chose ne va pas bien et il se bloque! des conseils sur ce que je peux faire mal?

grâce à l'aide de gens sympathiques, le malloc fonctionne maintenant, mais le remplissage des nœuds échoue!

est ici tout le code de la fonction:

int init(int *nodeNum, int ***neighbours, char *arg, struct node **nodes){ 
FILE *file; 
char buffer[4]; 
int i,y,distance; 

if(strcmp(arg,"-l")==0){ 
     file = fopen("C:\\Users\\trendkiller\\thesis\\matrix.txt","r"); 
     printf("parsing adjacency matrix from file\n\n"); 
     //file = fopen ("C:\\Users\\trendkiller\\thesis\\matrix.txt", "r") ; 
     *nodeNum = atoi(fgets(buffer,4,file)); 
     *neighbours=malloc(*nodeNum*sizeof(int *)); 
     for(i=0;i<*nodeNum;i++){ 
      (*neighbours)[i] = malloc(*nodeNum*sizeof(int *)); 
     } 
     printf("this prints\n"); 
     printf("number of nodes: %s", buffer); 
     for(i=0;i<*nodeNum;i++){ 
      for(y=0;y<*nodeNum;y++){ 
       fgets(buffer,4,file); 
       (*neighbours)[i][y]=atoi(buffer); 
          } 
     } 


    } 
    else{ 
     *nodeNum = atoi(arg); 

     *neighbours=malloc(*nodeNum*sizeof(int *)); 
     printf("this prints\n"); 
     for(i=0;i<*nodeNum;i++){ 
      (*neighbours)[i] = malloc(*nodeNum*sizeof(int *)); 
     } 

     *nodes=malloc(*nodeNum*sizeof(struct node)); 

     for(i=0;i<30;i++){ 
      (*nodes)[i].x=rand()%100; 
      (*nodes)[i].y=rand()%100; 
     } 
     printf("this prints\n"); 

     printf("creating new adjacency matrix\n\n"); 
     for(i=0; i<*nodeNum; i++){ 
      for(y=0; y<*nodeNum; y++){ 
       distance=sqrt((((*nodes)[y].x-(*nodes)[i].x)*((*nodes)[y].x-(*nodes)[i].x))+(((*nodes)[y].y-(*nodes)[i].y)*((*nodes)[y].y-(*nodes)[i].y))); 
       if(i==y){ 
        (*neighbours)[i][y]=-1; 
       } 
       else if(distance<=20){ 
        (*neighbours)[i][y]=1; 
       } 
       else { 
        (*neighbours)[i][y]=0; 
       } 
      } 

     } 

     file = fopen("C:\\Users\\trendkiller\\thesis\\matrix.txt","a+"); 
     fprintf(file,"%d\n",*nodeNum); 
     for(i=0;i<*nodeNum;i++){ 
      for(y=0;y<*nodeNum;y++){ 
       fprintf(file,"%d\n", (*neighbours)[i][y]); 
      } 
     } 
    } 

return 0;

}

Merci d'avance pour votre aide!

+0

Vous avez un pointeur sur pointeur, pas un tableau 2D. Vous pouvez utiliser cela comme une émulation pour cela, mais pourquoi ne pas simplement utiliser des tableaux dynamiques 2D comme ils viennent en C depuis C99. De plus, le but de vos 'arg' et' noeuds 'n'est pas clair. –

+0

Je ne suis pas sûr de ce que vous voulez dire "juste utiliser des tableaux 2D dynamiques" Je pensais que c'est ce que je fais! (juste pas avec succès ..) le paramètre arg est le premier argument de la ligne de commande, qui est un nombre ou une chaîne. si c'est un nombre je crée autant de noeuds dans le "noeud de noeud * de structure" sinon si c'est une chaîne j'analyse une matrice d'adjacence (voisins) d'un fichier qui remplit aussi le tableau "noeud de noeud * noeuds". – tk66

Répondre

1

Le problème est que neighbours est passé par la valeur, donc les modifications à l'intérieur de la fonction n'ont aucun effet. Vous devez passer par pointeur, et le modifier indirectement:

int init(int *nodeNum, int ***neighbours_ptr, char *arg, struct node *nodes) { 
    *neighbours_ptr = malloc(*nodeNum*sizeof(int *)); 
    for(i=0;i<*nodeNum;i++){ 
     (*neighbours_ptr)[i] = malloc(*nodeNum*sizeof(int *)); 
    } 
} 

Vous devez également passer &neighbours au lieu de neighbours comme second argument de init.

+0

merci, ça a du sens de cette façon! mais ça ne marche toujours pas! – tk66

+0

@ tk66 Pourriez-vous élaborer sur la partie "ne fonctionne pas"? Est-ce que ça plante? Que voyez-vous dans le débogueur? Par ailleurs, pourquoi passez-vous un pointeur vers 'nodeNum' plutôt que' nodeNum', et pourquoi passez-vous des 'noeuds '? – dasblinkenlight

+0

il n'allouait pas la mémoire correctement mais maintenant il le fait! mais maintenant il se bloque quand j'essaye de remplir le tableau de noeuds. Je le passe comme un argument parce que j'ai besoin de malloc ainsi et l'utilise de la fonction principale plus tard. nodeNum est aussi quelque chose que je dois utiliser plus tard dans la fonction principale et il obtient sa valeur dans la fonction init lors de l'analyse des arguments ou d'un fichier. – tk66

0

Dans le code exemple que vous donnez une erreur est ici:

neighbours[i] = malloc(*nodeNum*sizeof(int *)); 

où il devrait être

neighbours[i] = malloc(*nodeNum*sizeof(int)); 

Pourquoi utilisez-vous une émulation d'un tableau 2D au lieu d'un vrai? Cela fonctionne depuis C99:

int (*neighbours)[nodeNum] = malloc(sizeof(int[nodeNum][nodeNum])); 

Vous ne voudriez pas avoir besoin d'un init comme le vôtre qui attribue simplement la mémoire. Pourquoi vous passez un pointeur sur nodeNum et pas directement sur la valeur? Si vous avez toujours besoin d'une fonction init qui effectue une initialisation et pas seulement une allocation.L'interface ressemblerait à quelque chose comme

void init(size_t nodeNum, int neighbours[nodeNum][nodeNum]); 
+0

J'ai besoin de la fonction init car elle fait aussi d'autres choses ... et j'ai besoin du nodeNum comme pointeur car cela dépend de l'argument des args, qui est analysé dans l'init. Je vais éditer mon post pour inclure le code entier de la fonction init! Merci pour votre temps! – tk66

Questions connexes