Programmation en C initialiser le tableau 2D de manière dynamique
Je suis en train de faire quelque chose de stupide, et je ne peux pas mettre mon doigt sur exactement ce que:
void init_data(double **data, int dim_x, int dim_y) {
int i,j,k;
data = (double **) malloc(sizeof(double) * dim_x);
for (k = 0; k < dim_y; k++) {
data[k] = (double *) malloc(sizeof(double) * dim_y);
}
for (i = 0; i < dim_x; i++) {
for (j = 0; j < dim_y; j++) {
data[i][j] = ((double)rand()/(double)RAND_MAX);
}
}
}
Et dans main (), je ne les suivants:
double **dataA;
int dim = 10;
init_data(&dataA, dim, dim);
Mais puis à droite après cela, lorsque j'essaie d'impression les données que le programme se bloque:
int i,j;
for(i=0;i<dim;i++)
for(j=0;j<dim;j++)
printf("%d\n", dataA[i][j]);
Ce qui me manque?
Grâce
- J'ai posté ma réponse, pourriez-vous s'il vous plaît vérifier si cela fonctionne?
Vous devez vous connecter pour publier un commentaire.
Vous faites quelques erreurs dans votre pointeurs. Vous êtes de passage le &dataA à init_data, de sorte que le type d'argument devrait être ***double, à la place de **double. Aussi votre premier malloc est l'initialisation d'un tableau de pointeurs, pas un tableau de double, de sorte qu'il devrait être sizeof(double *) * dim_x. Le code ci-dessous devrait fonctionner.
Votre première boucle devrait également avoir la condition k < dim_x au lieu de k < dim_y. Il n'a pas d'importance dans le cas présent, puisque les deux dimensions sont les mêmes, mais causerait des problèmes si ils ne l'étaient pas. Enfin, vous devez utiliser %f au lieu de %d dans ton printf, comme les chambres doubles sont stockées dans un format différent de celui des entiers, et vous êtes susceptible d'obtenir le charabia, plutôt que ce que vous voulez.
La
dataA
demain
n'est jamais en cours d'initialisation. Le pointeurdata
que vous passez àinit_data
est immédiatement remplacé par un pointeur retourné parmalloc
.*data = malloc ...
Si je veux allouer de la mémoire et de l'initialisation d'un conseil, je voudrais:
Donc initiliaze votre conseil d'administration, il suffit de faire:
Dans votre cas, l'utilisation
double
au lieu deint
.Vous n'êtes pas le réglage de la valeur de dataA dans main().
Je voudrais changer la définition de init_data pour retourner le pointeur pour les nouvelles données. Quelque chose comme ceci:
Puis dans main()
Vous code a plusieurs problèmes, dont la majorité peut être identifié facilement en tournant vos avertissements du compilateur jusqu'.
Le premier problème est que
init_data
s'attend à undouble**
que c'est le premier argument, cependant, vous êtes en passant undouble***
(vérifiez vos avertissements du compilateur). Depuisinit_data
est en cours d'initialisation de la mémoire que c'est l'allocation elle-même, par opposition à l'initialisation d'un bloc de mémoire que vous alloués par ailleurs, vous pouvez supprimer que le premier argument et le retour d'undouble**
à la place.Vous êtes également l'allocation d'une quantité insuffisante de mémoire pour
data
. Ce que vous voulez, c'est assez de mémoire pourdim_x
montant dedouble*
, pasdouble
. Vous pouvez le faire aussi avecsizeof(*data)
(type de*data
estdouble*
) au lieu desizeof(double*)
.Puisqu'il y a
dim_x
double*
s dans les données etdim_y
double
s dans le bloc de mémoire pointé par chacun de cesdouble*
s, votre première boucle d'itération jusqu'àdim_x
, et votre seconde jusqu'àdim_y
.Aussi, le casting de la suite de
malloc
(en jetant unvoid*
) dans C est inutile. Il y a des réponses sur ce site qui va vous dire pourquoi il est préférable que vous ne le faites pas.Un autre problème a à voir avec la
printf
spécificateur de format.%d
est pourint
,%f
est utilisé pourdouble
(%lf
lors de l'utilisation descanf
).Maintenant, si vous ajoutez le code à
free
votre mémoire allouée et exécuter votre programme grâce à quelque chose comme valgrind, vous verrez que vous n'êtes plus rien faire coquine en mémoire.Le code de travail ressemblerait à:
Première erreur est que vous êtes de passage à
&dataA
à la fonctioninit_data
, mais dans la fonction que vous recevez cette valeur commedouble **
il devrait êtredouble ***
. Parce que vous êtes de passage du pointeur d'une variable de typedouble **
. Doncinit_data
prototype de fonction doit être comme ci-dessousDeuxième erreur est dans le dessous de tresorerie
Cette déclaration doit être comme ci-dessous
Parce que nous venons de mettre à jour le pointeur de variable
dataA
. De sorte que nous serons en mesure de l'afficher dansmain
fonction après la commande vient deinit_data
fonction. Et nous aussi, nous allons stocker pointeur vers un double. Il devrait donc êtresizeof(double *)
Mise à jour de votre
init_data
fonction comme ci-dessous