Je dois avoir essayé 20 façons de faire maintenant. J'ai vraiment besoin d'aide, peu importe ce que je fais, j'obtiens une erreur similaire à celle-ci.
a value of type "int" cannot be used to initialize an entity of type "int (*)[30]"
c'est-à-dire que cela m'obtiendra une telle erreur
int(*array)[160] = malloc((sizeof *array) * 10);
et faire quelque chose comme ça
int** Make2DintArray(int arraySizeX, int arraySizeY) {
int** theArray;
theArray = (int**) malloc(arraySizeX*sizeof(int*));
int i;
for (i = 0; i < arraySizeX; i++)
{
theArray[i] = (int*) malloc(arraySizeY*sizeof(int));
}
return theArray;
}
va me faire ça
"void *(size_t)" in "memory.c" at line 239 and: "int()"
quelqu'un at-il une solution pour allouer avec succès un 2dArray d'int [160] [10]
Les deux compilent bien pour moi. La première erreur est courante lorsque vous oubliez #include <stdlib.h>
avant d'utiliser des fonctions déclarées dans les mêmes (comme malloc(size_t)
), ce que j'ai fait ne pas oublier de le faire.
C a des comportements de compilation intéressants, parmi lesquels la possibilité d'invoquer une fonction qui n'a jamais été vue auparavant (ni mise en œuvre de définition de prototype ni ). En rencontrant un tel appel, C suppose que la fonction est:
int
Par exemple, la fonction est implicitement supposée être de la forme:
int func();
Souvent, vous ne le remarquerez même pas, sauf pour les avertissements de votre compilateur qui signalent quelque chose à l'effet de:
Warning: implicit declaration of `func` assumed to return `int`
et si vous êtes dans le coup, vos niveaux d'avertissement sont activés et les avertissements en tant qu'erreurs sont activés et vous le verrez.
Et si vous ne le faites pas? Et si la "chose" renvoyée par la fonction ne peut pas être représentée par le contenu par la taille des données dans une implémentation int
? Et si, par exemple, int
était 32 bits, mais que les pointeurs de données étaient 64 bits? Par exemple, supposons que char *get_str()
est déclaré dans un fichier d'en-tête que vous n'incluez pas , et implémenté dans un fichier .c que vous compiler et lier avec votre programme, qui ressemble à ceci:
#include <stdio.h>
// Note: NO prototype for get_str
int main()
{
char *s = get_str();
printf("String: %s\n", s);
return 0;
}
Eh bien, le compilateur devrait vomir, vous disant que int
et char*
Ne sont pas compatibles (peu de temps après qu'il vous avertit get_str
Est supposé renvoyer int
). Mais que faire si vous forcez la main du compilateur en en lui disant de faire un char*
D'une manière ou d'une autre:
#include <stdio.h>
// Note: NO prototype for get_str
int main()
{
char *s = (char*)get_str(); // NOTE: added cast
printf("String: %s\n", s);
return 0;
}
Maintenant, sans les avertissements en tant qu'erreurs activés, vous obtiendrez un avertissement de déclaration implicite, et c'est tout. Le code se compilera. Mais sera-t-il exécuté ? Si sizeof(int)
! = sizeof(char*)
, (32 bits vs 64 bits) probablement pas. La valeur renvoyée par get_str
Est un pointeur 64 bits, mais l'appelant suppose que seuls 32 bits sont renvoyés, puis le force à un pointeur 64 bits. En bref, le casting a caché l'erreur et ouvert la boîte de Pandore de comportement indéfini.
Alors, comment tout cela est-il lié à votre code? En n'incluant pas <stdlib.h>
, Le compilateur ne sait pas ce qu'est malloc
. Il suppose donc qu'il est de la forme:
int malloc();
Ensuite, en transtypant le résultat en (int**)
, Vous dites au compilateur "tout ce qui en sort, faites-en un int**
". Au moment de la liaison, _malloc
Est trouvé (pas de signature de paramètre via un changement de nom comme C++), câblé et votre programme est prêt à faire la fête. Mais sur votre plate-forme int
et les pointeurs de données ne sont pas pas de la même taille, vous vous retrouvez donc avec plusieurs conséquences indésirables:
sizeof(int) == sizeof(int**)
.Donc, vous construisez cela sur votre boîte Debian 32 bits, tout semble bien. Vous remettez vos devoirs au professeur qui le construit sur son Mac 64 bits et il se bloque, vous échouez la tâche, échouez en classe, abandonnez vos études et passez les dix prochaines années à caresser le chat tout en regardant Seinfeld rediffuser dans le sous-sol de votre mère me demande ce qui a mal tourné. Aie.
Ne traitez pas le casting comme une balle d'argent. Ce n'est pas le cas. En C, il est nécessaire loin moins souvent que les gens l'utilisent, et s'il est utilisé au mauvais endroit, peut cacher des erreurs catastrophiques. Si vous trouvez un point dans votre code où quelque chose ne se compilera pas sans conversion en dur, regardez à nouveau . À moins que vous ne soyez absolument, positivement sûr que le casting est la bonne chose à faire, les chances sont que mal .
Dans ce cas, il a caché la vraie erreur, que vous avez négligé de donner suffisamment d'informations à votre compilateur pour savoir ce que malloc
fait vraiment.
Essaye ça:
int **array;
array = malloc(rows * sizeof(int *));
for (i = 0; i < rows; i++)
array[i] = malloc(cols * sizeof(int));
// Some testing
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++)
array[i][j] = 0; // or whatever you want
}
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++)
printf("%d ", array[i][j]);
}
Dans votre cas, les lignes = 160 et cols = 10. Est une solution possible.
Avec cette approche, vous pouvez utiliser les deux index:
Pour allouer le tableau:
int *array = malloc(sizeof(int) * 160 * 10);
Ensuite, utilisez du code comme:
array[10 * row + column] = value;
(Où row
va de 0 à 159 inclus et column
va de 0 à 9 inclus.)
J'ai une note pour la réponse de rendon:
Pour son code, Visual C++ indique pour chaque opération "=": error C2440: '=' : cannot convert from 'void *' to 'int **'
En faisant quelques changements, cela fonctionne pour moi, mais je ne suis pas sûr que cela fasse la même chose, j'ai donc peur d'éditer son code. Au lieu de cela, voici le code qui semble fonctionner pour une première impression.
int **a;
a = (int **)malloc(rows * sizeof(int));
for (i = 0; i < rows; i++)
{
a[i] = (int *)malloc(cols * sizeof(int));
}
for (j=0;j<rows;j++)
{
for (i=0;i<cols;i++)
{
a[i][j] = 2;
}
}
En fait, je l'ai fait avec un struct
personnalisé au lieu de int
s mais je pense que dans tous les cas cela devrait fonctionner.
Ne me dérange pas, j'ajoute juste un exemple en utilisant calloc
void allocate_fudging_array(int R, int C)
{
int **fudging_array = (int **) calloc(R, sizeof(int *));
for(int k = 0; k < R; k++)
{
fudging_array[k] = (int*) calloc(C, sizeof(int));
}
}
// a helper function to print the array
void print2darr(int **arr, int R, int C)
{
for(int i = 0; i < R; i++)
{
for(int j = 0; j < C; j++)
{
printf(" %d ", arr[i][j]);
}
printf("\n");
}
}