sizeof / sizeof 'type d'un element';
Mais le sizeof du tableau ne fonctionne plus une fois que je l'ai passe en paramètre d'une fonction.
Ou est le problème ?
#include
using namespace std;
int func(int array[], int* pointer)
{
int n1 = sizeof(array); // no, it isn't
int n2 = sizeof(pointer);
cout << "[]" << n1 << endl;
cout << "*" << n2 << endl;
return n1 - n2;
}
int main()
{
int v[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
cout << "local " << sizeof v << endl;
func (v, v);
return 0;
}
Résultat :
local 40
[]4
*4
desole pour le code illisible, j'ai pas réussi a faire mieux.
# Commentaire supprimé
Posté par Anonyme . Évalué à 2.
Ce commentaire a été supprimé par l’équipe de modération.
[^] # Re: Le paramètre de la fonction
Posté par locnet . Évalué à 1.
Ca explique que n1 = n2.
Mais pourquoi n1 != 'sizeof v ' ?
Mais surtout, est-il possible d'obtenir la taille réelle du tableau (40) depuis la fonction func ?
[^] # Commentaire supprimé
Posté par Anonyme . Évalué à 4.
Ce commentaire a été supprimé par l’équipe de modération.
[^] # Re: Le paramètre de la fonction
Posté par Yann Hodique (site web personnel) . Évalué à 2.
sizeof est un operator résolu à la compilation, donc rien d'étonnant à ce que sur des paramètres il ne puisse que donner la taille du pointeur.
Je ne sais pas exactement comment gcc fait, mais il doit se souvenir que v n'est pas n'importe quel int*, mais celui initialisé juste au dessus.
à noter que même dans le main(), un simple sizeof((int*)v) donne bien 4. (ce qui est heureux d'ailleurs :))
En résumé, non il n'est pas possible d'obtenir 40 dans ta fonction sans retenir l'info quelque part.
[^] # Re: Le paramètre de la fonction
Posté par B. franck . Évalué à 0.
je crois que c'est une fonctionnalité du c++
que de renvoyer la bonne taille ( (indexmax+1) * sizeof(typeelement) )
je l'avais oublié aussi en ayant passé trop de temps à
faire du perl ou du c...
[^] # Re: Le paramètre de la fonction
Posté par aedrin . Évalué à 2.
en fait, c'est plutôt le fait que gcc donne la "bonne" taille dans le main() qui est "surprenant"
à l'intérieur du main, v est un tableau statique dont la taille a été déterminée à la compilation (déclaration en []). rien d'étonnant à ce que sizeof trouve le bon résultat. v se comporte alors comme un pointeur sur entier, mais ce n'est pas un pointeur sur entier, c'est un bon vieux tableau statique à taille fixe.
# vu que...
Posté par B. franck . Évalué à 2.
de tableau enrichie de fonction de détermination de taille
ou une variable d'instance stockant cette taille?
[^] # Re: vu que...
Posté par Sebastien . Évalué à 2.
const unsigned int theSize = myVect.size();
std::cout << "the size = " << theSize << std::endl;
C'est du C++, alors pourquoi ne pas utiliser les classes qui sont deja la ?
Sauf si le but est didactique, je ne vois pas trop l'interet de recoder une enieme classe de tableaux.
[^] # Re: vu que...
Posté par B. franck . Évalué à 1.
bête ?!
Je suis pas trop adepte de l'"obfuscated C++" (rapport au prefixe std::)
ni des "vector" d'entier (template?) pour manipuler un tableau d'entiers...
Je veux dire par là que j'aurais le défaut de réimplémenter
une roue simple plutôt que d'utiliser l'arsenal multi-essieux
que tu as apparemment la bonne habitude de manipuler...
(ou encore que je n'utilise pas assez c++ pour faire ça :\ )
[^] # Re: vu que...
Posté par Sebastien . Évalué à 4.
Ensuite dire que c'est du code obscure parce qu'il y a le namespace std qui est prefixe devant... c'est limite de la mauvaise foi : on peut toujours mettre un "using namespace std;" (soit dit en passant, mettre ce genre de chose dans un header, c'est mal, cela pollue l'espace de nommage des clients du code en question. Bon pour std c'est pas trop grave, c'est le standard mais c'est quand meme "bad practice")
Je dis pas que c'est simple a utiliser *des le debut*, mais l'interface des conteneurs de la STL est assez homogene. Une fois bien familiarise avec un des conteneurs (vector<T> par exemple) on peut ensuite facilement utiliser les autres conteneurs avec un minimum de connaissances a acquerir en plus.
De plus une fois qu'on a goute aux facilites de manipulation des conteneurs de la STL et surtout experimente un peu la panoplie d'algorithmes a notre disposition... Coder devient plus facile, plus concis et plus clair (donc moins de bugs?).
Osons les classes de la STL partie integrante des built-ins de C++ :P
[^] # Re: vu que...
Posté par B. franck . Évalué à 1.
A cause de toi je vais encore passer des nuits blanches
tout ça parce que tu m'as donné envie d'approfondir
la stl !
ralala, le corps il suit plus !
[^] # Re: vu que...
Posté par locnet . Évalué à 1.
En fait, je code justement a coder une classe Vecteur proche de vector.
Je cherchais à autoriser une construction de la forme :
Vecteur v( {1.0, 2.0)};
ou bien Vecteur v( (double[]){1.0, 2.0)};
et une affectation de la forme
v= {1.0, 2.0);
ou bien v = (double[]){1.0, 2.0);
Mais si c'est pas possible, tant pis.
Question subsidiaire, l'operateur delete[] se debrouille comment pour connaitre la taille de la mémoire a desallouer ? C'est au niveau du systeme (donc inaccessible) ?
[^] # Re: vu que...
Posté par aedrin . Évalué à 3.
Tout objet créé ***statiquement*** (ie à la compilation) de cette manière sera automatiquement détruit lorsque tu sortiras de la portée ou il a été créé (au prochain '}' pour un objet local, lors d'une sortie de fonction pour une variable locale, lors de la sortie du programme pour une variable globale).
Par contre pour stocker des grands tableaux (10, ça va je te rassure) ou pour des gros objets, il vaut mieux utiliser le tas, qui est prévu pour ça.
Le tas permet de créer ***dynamiquement*** les objets, c'est-à-dire à la demande. Pour créer un tableau de taille 10 dynamiquement, tu feras un int* v = new int[10];
Mais du coup il ne faut pas oublier de l'effacer, sinon il y aura des fuites mémoires : delete[] v;
Dans le cas de la pile, la gestion mémoire est gérée par le système grace à une... pile (et oui), donc c'est très simple tu n'y peux rien. Par contre, dans le cas du tas le système gère la mémoire de manière plus compliquée (quels blocs ont été alloués avec quelle taille, quels blocs viennent d'être désalloués, quel est le prochain bloc libre, classement des blocs libres suivant leur taille et la fragmentation mémoire, etc...) mais la bonne nouvelle, c'est que si tu es ***très*** motivé, tu peux surcharger ce comportement et gérer toi même la mémoire, mais bon courage !
Si ça t'intéresses, il n'y a qu'à surcharger les opérateurs ::new ::delete globaux ou bien les new delete propre à une classe donnée.
# Passage
Posté par Sisyphe Plâtrier . Évalué à 3.
Mais un int[10] n'est pas une l-value, ni passable directement en paramètre.
Par contre, int v[10] -> int v[] == int *v est possible
(il suffit de prendre l'adresse du premier élément) et utilisé pour le passage de paramètres.
L'exemple suivant affiche "size is obviously : 20\nnot so obviously : 4 ".
namespace nSizeof
{
void func1(int faTruc[5])
{
// the [5] ne sert à rien
cout << "not so obviously : " << sizeof(*faTruc) << endl;
}
void func5(int (*faTruc)[5])
{
cout << "size is obviously : " << sizeof(*faTruc) << endl;
}
bool doTest()
{
int lDummy = 5;
int laTab5[] = {1,2,3,4,5};
func5(&laTab5);
func1(laTab5);
//int laTab5_2[5];
//laTab5_2 = laTab5; // not a l-value
//laTab5_2 = (int*)laTab5; // no conversion to array types
//laTab5 = &lDummy; // idem
return true;
}
};
int main()
{
nSizeof::doTest();
return 0;
}
indent :(
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.