J'apprends à créer des tableaux 1D dynamiques en C. Le code ci-dessous essaie de faire ce qui suit:
malloc
, créez un tableau dynamique de longueur 10
, qui contient des valeurs de type double
.j/100
pour j = 0, 1,..., 9
. Imprimez-le ensuite.realloc
.j/100
et réimprimez chaque entrée.Essai:
double* data = (double*)malloc(10*sizeof(double));
for (j=0;j<10;j++)
{
data[j]= ((double)j)/100;
printf("%g, ",data[j]);
}
printf("\n");
data = (double*)realloc(data,11*sizeof(double));
for (j=0;j<11;j++)
{
if (j == 10){ data[j]= ((double)j)/100; }
printf("%g, ",data[j]);
}
free((void*) data);
Questions
Suis-je en train de coder ce droit?
Les didacticiels que j'ai trouvés utilisent malloc
sans mettre le (double*)
devant. Par exemple.,
int * pointeur;
pointeur = malloc (2 * sizeof (int));
Cela ne se compile pas pour moi sur Visual Studio 2010, Windows 7. Le message d'erreur est
la valeur de type void ne peut pas être affectée à l'entité de type
int
.
Pourquoi ça marche pour ces tutoriels et pas pour moi? Ai-je raison de supposer que c'est parce que les compilateurs qu'ils utilisent remplissent automatiquement le (int*)
pour eux dans mon exemple?
Tu es proche.
En C (au moins depuis la version 1989 de la norme), la conversion avant malloc
et realloc
est inutile, car C peut convertir des valeurs de type void *
En int *
Sans plâtre. Ceci est pas vrai pour C++, donc en fonction de l'erreur que vous obtenez, il semble que vous compiliez ce code en C++ et non en C. Consultez la documentation de VS2010 pour déterminer comment compiler le code comme C.
Voici mon style préféré pour écrire un appel malloc
:
double *data = malloc(10 * sizeof *data);
Comme le type de l'expression *data
Est double
, sizeof *data
Est équivalent à sizeof (double)
. Cela signifie également que vous n'avez pas à ajuster vos appels malloc
si le type de data
change.
Quant à l'appel realloc
, il est plus sûr d'affecter le résultat à une valeur de pointeur temporaire. realloc
renverra NULL s'il ne peut pas étendre le tampon, il est donc plus sûr d'écrire
double *tmp;
...
tmp = realloc(data, 11 * sizeof *data);
if (!tmp)
{
// could not resize data; handle as appropriate
}
else
{
data = tmp;
// process extended buffer
}
Sachez que la prise en charge de Microsoft pour C prend fin avec la version 1989 du langage; il y a eu deux révisions de la norme de langage depuis lors, qui ont introduit de nouvelles fonctionnalités et des anciennes obsolètes. Ainsi, bien que certains compilateurs C prennent en charge les fonctionnalités C99 comme les déclarations et le code mixtes, les tableaux de longueur variable, etc., VS2010 ne le fera pas.
1) Suis-je en train de coder ce droit?
La plupart. Mais data = (double*)realloc(data,11*sizeof(double));
perd la référence à la mémoire allouée si realloc
échoue, vous devez utiliser un pointeur temporaire pour conserver la valeur de retour de realloc
et vérifier si c'est NULL
(et vous devez également vérifier la valeur de retour de malloc
).
2) Tutoriels J'ai trouvé utiliser malloc sans mettre le (double *) devant.
En C, malloc
renvoie un void*
qui peut être implicitement converti en tout autre type de pointeur, donc aucun transtypage n'est nécessaire (et largement déconseillé car un transtypage peut masquer des erreurs). Visual Studio compile apparemment le code en C++ où la conversion est requise.
En C, vous ne devez pas transtyper la valeur de retour de malloc()
.
De plus, c'est une mauvaise idée de coder le type dans l'argument malloc()
. C'est une meilleure façon:
double* data = malloc(10 * sizeof *data);