Tout d'abord, voici un code:
int main()
{
int days[] = {1,2,3,4,5};
int *ptr = days;
printf("%u\n", sizeof(days));
printf("%u\n", sizeof(ptr));
return 0;
}
Existe-t-il un moyen de connaître la taille du tableau qui ptr
pointe vers (au lieu de simplement donner sa taille, qui est de quatre octets sur un système 32 bits)?
Réponses:
Non, tu ne peux pas. Le compilateur ne sait pas vers quoi pointe le pointeur. Il existe des astuces, comme terminer le tableau avec une valeur hors bande connue, puis compter la taille jusqu'à cette valeur, mais ce n'est pas utilisé
sizeof()
.Une autre astuce est celle mentionnée par Zan , qui consiste à cacher la taille quelque part. Par exemple, si vous allouez dynamiquement le tableau, allouez un bloc un entier plus grand que celui dont vous avez besoin, cachez la taille dans le premier entier et retournez
ptr+1
comme pointeur vers le tableau. Lorsque vous avez besoin de la taille, décrémentez le pointeur et regardez la valeur cachée. N'oubliez pas de libérer tout le bloc à partir du début, et pas seulement le tableau.la source
La réponse est non."
Les programmeurs C stockent la taille du tableau quelque part. Il peut faire partie d'une structure, ou le programmeur peut tricher un peu et
malloc()
plus de mémoire que demandé afin de stocker une valeur de longueur avant le début du tableau.la source
Pour les tableaux dynamiques ( malloc ou C ++ nouveau ), vous devez stocker la taille du tableau comme mentionné par d'autres ou peut-être créer une structure de gestionnaire de tableau qui gère l'ajout, la suppression, le comptage, etc. Malheureusement, C ne le fait pas aussi bien que C ++ puisque vous devez essentiellement le construire pour chaque type de tableau différent que vous stockez, ce qui est lourd si vous avez plusieurs types de tableaux que vous devez gérer.
Pour les tableaux statiques, tels que celui de votre exemple, une macro courante est utilisée pour obtenir la taille, mais elle n'est pas recommandée car elle ne vérifie pas si le paramètre est vraiment un tableau statique. Cependant, la macro est utilisée dans du code réel, par exemple dans les en-têtes du noyau Linux, bien qu'elle puisse être légèrement différente de celle ci-dessous:
Vous pouvez google pour des raisons de se méfier de macros comme celle-ci. Faites attention.
Si possible, le stdlib C ++ tel que vector qui est beaucoup plus sûr et plus facile à utiliser.
la source
ARRAY_SIZE
macro fonctionne toujours si son argument est un tableau (c'est-à-dire une expression de type tableau). Pour votre soi-disant "tableau dynamique", vous n'obtenez jamais un "tableau" réel (expression de type tableau). (Bien sûr, vous ne pouvez pas, car les types de tableaux incluent leur taille au moment de la compilation.) Vous obtenez simplement un pointeur sur le premier élément. Votre objection "ne vérifie pas si le paramètre est vraiment un tableau statique" n'est pas vraiment valide, car ils sont différents car l'un est un tableau et l'autre ne l'est pas.Il existe une solution propre avec des modèles C ++, sans utiliser sizeof () . La fonction getSize () suivante renvoie la taille de tout tableau statique:
Voici un exemple avec une structure foo_t :
Production:
la source
T (&)[SIZE]
. Pouvez-vous expliquer ce que cela signifie? Vous pouvez également mentionner constexpr dans ce contexte.SIZE
comme argument, c'est un paramètre de modèle qui a déjà connu par la définition de la fonction.)Pour cet exemple spécifique, oui, il y en a, SI vous utilisez des typedefs (voir ci-dessous). Bien sûr, si vous le faites de cette façon, vous pouvez tout aussi bien utiliser SIZEOF_DAYS, car vous savez vers quoi pointe le pointeur.
Si vous avez un pointeur (void *), comme renvoyé par malloc () ou similaire, alors, non, il n'y a aucun moyen de déterminer la structure de données vers laquelle le pointeur pointe et donc, aucun moyen de déterminer sa taille.
Production:
la source
Comme toutes les bonnes réponses l'ont indiqué, vous ne pouvez pas obtenir ces informations uniquement à partir de la valeur du pointeur pourri du tableau. Si le pointeur pourri est l'argument reçu par la fonction, alors la taille du tableau d'origine doit être fournie d'une autre manière pour que la fonction connaisse cette taille.
Voici une suggestion différente de ce qui a été fourni jusqu'à présent, qui fonctionnera: passez plutôt un pointeur vers le tableau. Cette suggestion est similaire aux suggestions de style C ++, sauf que C ne prend pas en charge les modèles ou les références:
Mais, cette suggestion est un peu idiote pour votre problème, car la fonction est définie pour connaître exactement la taille du tableau qui est passé (par conséquent, il n'est pas nécessaire d'utiliser sizeof du tout sur le tableau). Cependant, il offre une certaine sécurité de type. Il vous interdira de passer dans un tableau d'une taille indésirable.
Si la fonction est censée pouvoir fonctionner sur n'importe quelle taille de tableau, vous devrez fournir la taille de la fonction comme information supplémentaire.
la source
Il n'y a pas de solution magique. C n'est pas un langage réflexif. Les objets ne savent pas automatiquement ce qu'ils sont.
Mais vous avez plusieurs choix:
la source
Ma solution à ce problème consiste à enregistrer la longueur du tableau dans un tableau struct en tant que méta-informations sur le tableau.
Mais vous devez vous soucier de définir la bonne longueur du tableau que vous souhaitez stocker, car il n'y a aucun moyen de vérifier cette longueur, comme nos amis l'ont expliqué massivement.
la source
Vous pouvez faire quelque chose comme ça:
la source
Non, vous ne pouvez pas utiliser
sizeof(ptr)
pour trouver la taille du tableauptr
vers laquelle pointe.Bien que l'allocation de mémoire supplémentaire (plus que la taille du tableau) sera utile si vous souhaitez stocker la longueur dans un espace supplémentaire.
la source
La taille des jours [] est de 20, ce qui n'est pas un élément * la taille de son type de données. Alors que la taille du pointeur est de 4, peu importe ce qu'il pointe. Parce qu'un pointeur pointe vers un autre élément en stockant son adresse.
la source
array_size passe à la variable de taille :
L'utilisation est:
la source
Dans les chaînes, il y a un
'\0'
caractère à la fin de sorte que la longueur de la chaîne peut être obtenue en utilisant des fonctions commestrlen
. Le problème avec un tableau entier, par exemple, est que vous ne pouvez pas utiliser de valeur comme valeur finale, donc une solution possible consiste à adresser le tableau et à utiliser comme valeur finale leNULL
pointeur.la source
NULL
est probablement l'alternative la moins efficace imaginable pour simplement stocker un élément séparésize
directement. Surtout si vous utilisez tout le temps cette couche supplémentaire d'indirection.