Comment trouver le "sizeof" (un pointeur pointant sur un tableau)?
Tout d'abord, voici un peu de 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;
}
Est-il un moyen de savoir la taille de la matrice que ptr
pointe (au lieu de simplement donner de sa taille, qui est de quatre octets sur un système 32 bits)?
- J'ai toujours utilisé des parens avec sizeof sûr, il la fait ressembler à un appel de fonction, mais je pense que c'est plus clair.
- Pourquoi pas? Avez-vous quelque chose contre le superflu des parenthèses? Je pense qu'il lit un peu plus facilement avec eux, moi-même.
- Surtout si vous êtes en train de faire quelque chose comme malloc(sizeof(int) * 4).
- Heh. Je les trouve trop encombrer, et ... inutile, puisqu'il fait il ressemble à un appel de fonction, qui elle ne l'est pas vraiment. Je ne considère pas que ce soit clair.
- eh bien .. en supposant que le, à gauche de l'appel est un pointeur sur int, j'aimerais écrire comme int *ptr = malloc(4 * sizeof *ptr); ce qui pour moi est beaucoup plus claires. Moins parens à lire, et à mettre le littéral constsant à l'avant, comme en mathématiques.
- ne pas allouer un tableau de pointeurs quand vous pensiez un tableau d'entiers!
- Il n'y a pas de "pointeur pointant sur un tableau" ici. Juste un pointeur pointant vers un int.
- Certains compilateurs n'ont construit ins pour cette fin, gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html
Vous devez vous connecter pour publier un commentaire.
Non, vous ne pouvez pas. Le compilateur ne sait pas ce que le pointeur pointe. Il y a des trucs, comme la fin du tableau avec un out-of-band de la valeur et puis en comptant la taille jusqu'à ce que la valeur, mais ce n'est pas à l'aide de sizeof.
Une autre astuce est celle mentionnée par Zan, qui est à ranger la taille quelque part. Par exemple, si vous êtes alloue dynamiquement le tableau, allouer un bloc un int plus grand que celui dont vous avez besoin, la planque de la taille à la première de type int, et le retour ptr+1 comme le pointeur vers le tableau. Lorsque vous avez besoin de la taille, décrémenter le pointeur et coup d'oeil à l'planqué valeur. N'oubliez pas de libérer l'ensemble du bloc de départ depuis le début, et pas seulement le tableau.
La réponse est "Non".
Ce que C programmeurs faire est de stocker 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 ce qui est demandé, afin d'y stocker une valeur de longueur avant le début de la matrice.
Pour les tableaux dynamiques (malloc ou C++ nouveau) vous avez besoin de stocker la taille de la matrice comme mentionné par d'autres, ou peut-être construire un tableau gestionnaire de la structure qui s'occupe d'ajouter, de supprimer, compter, etc. Malheureusement, C de ne pas le faire presque aussi bien que le C++ depuis en gros, vous avez à construire pour chaque différent type de tableau que vous stockez, ce qui est contraignant si vous disposez de plusieurs types de tableaux que vous avez besoin pour gérer.
Pour les tableaux statiques, comme dans votre exemple, il existe une macro permet d'obtenir la taille, mais il est pas recommandé qu'il ne vérifie pas si le paramètre est vraiment un tableau statique. La macro est utilisée dans le code réel, bien que, par exemple, dans le noyau de Linux les en-têtes bien qu'il peut être légèrement différent de celui ci-dessous:
Vous pouvez google pour raisons de se méfier des macros comme cela. Être prudent.
Si possible, le C++ stdlib comme vecteur qui est beaucoup plus sûr et plus facile à utiliser.
ARRAY_SIZE
macro fonctionne toujours si son argument est un tableau (c'est à dire l'expression de type tableau). Pour votre soi-disant "tableau dynamique", vous n'obtiendrez jamais un "tableau" (expression de type tableau). (Bien sûr, vous ne pouvez pas, depuis le tableau de types divers, notamment de leur taille au moment de la compilation.) Vous venez d'obtenir un pointeur vers le premier élément. Votre objection "de ne pas vérifier si le paramètre est vraiment un tableau statique" n'est pas vraiment valide, car ils sont différents de ce que l'on est un tableau et l'autre ne l'est pas.ARRAY_SIZE
macro, avec un nom différent, est utilisé dans le K&R C 2e édition. Pas une bonne pratique de nos jours, mais la langue elle-même n'offre pas de solution.Il y a une solution propre avec les modèles C++, sans l'aide de sizeof(). La suite getSize() fonction renvoie la taille d'un tableau statique:
Voici un exemple avec un foo_t structure:
De sortie:
T (&)[SIZE]
. Pouvez-vous expliquer ce que cela signifie? Vous pouvez également mentionner constexpr dans ce contexte.SIZE
comme un arg, c'est un modèle de param qui doit déjà être connu par la définition de la fonction.)std::size()
, qui est similaire à votregetSize()
fonction et en plus a une surcharge pour les conteneurs, qui fournissent unsize()
de la fonction membre.Pour cet exemple précis, oui, il est, SI vous utilisez des typedefs (voir ci-dessous). Bien sûr, si vous faites de cette façon, vous êtes aussi bien pour l'utilisation SIZEOF_DAYS, puisque vous savez ce que le pointeur pointe.
Si vous avez un (void * pointeur, comme retourné par malloc() ou autres, alors, non, il n'y a aucun moyen de déterminer quelle structure de données que le pointeur pointe et, par conséquent, aucun moyen de déterminer sa taille.
De sortie:
Il n'y a pas de solution magique. C est pas une réflexion de la langue. Les objets ne sont pas automatiquement savent ce qu'ils sont.
Mais vous avez beaucoup de choix:
Comme toutes les bonnes réponses vous l'avez dit, vous ne pouvez pas obtenir cette information à partir de la vétuste la valeur du pointeur de la matrice seule. Si le pourri pointeur est l'argument reçu par la fonction, la taille de la provenance tableau doit être fourni pour la fonction venir à savoir que la taille de l'.
Voici une suggestion différente de ce qui a été fourni jusqu'à maintenant,qui va travailler: Passer un pointeur vers le tableau à la place. Cette suggestion est similaire pour le style C++ suggestions, sauf que C ne prend pas en charge les modèles ou les références:
Mais, cette suggestion est un peu idiot de votre problème, puisque la fonction est définie pour connaître exactement la taille de la matrice qui est passé dans (et par conséquent, il n'est pas nécessaire d'utiliser sizeof à tous sur le tableau). Ce qu'il fait faire, cependant, est d'offrir un certain type de sécurité. Il va vous interdire de passer dans un tableau d'un format restreint.
Si la fonction est censée être capable de fonctionner sur n'importe quelle taille de tableau, alors vous aurez à fournir la taille de la fonction en tant qu'informations supplémentaires.
Ma solution à ce problème est de sauver la longueur du tableau dans une structure de Tableau comme un méta-informations sur le tableau.
Mais vous préoccuper de définir le droit longueur du tableau que vous souhaitez stocker, car il n'y a aucun moyen de vérifier cette longueur, à l'instar de nos amis massivement expliqué.
Taille de jours[] est 20 qui n'est pas d'éléments * taille de ce type de données.
Alors que la taille du pointeur est de 4, peu importe ce qu'il désigne.
Parce qu'un pointeur de points de d'autres de l'élément de stockage d'adresse.
Vous pouvez faire quelque chose comme ceci:
Non, vous ne pouvez pas utiliser
sizeof(ptr)
pour trouver la taille de la matrice deptr
pointe.Si l'allocation de la mémoire supplémentaire(plus que la taille de la matrice), vous sera utile si vous souhaitez stocker la longueur de l'espace supplémentaire.
array_size est de passer à la taille variable:
D'Usage:
salut dans les cordes il y a un
'\0'
de caractère à la fin on peut donc obtenir la tailled'une chaîne avec des fonctions comme
strlen
le problème avec un tableau d'entiers par exemple, c'est que u ne peut pas utiliser n'importe quelle valeur une valeur de fin donc une solution possible est de répondre à l'éventail et l'utiliser comme une valeur à la fin de laNULL
pointeurNULL
est probablement la moins efficace de rechange possibles et inimaginables pour l'enregistrement séparésize
directement. Surtout si vous avez réellement utilisation cette couche supplémentaire d'indirection tout le temps.