C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Taille d'une structure

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Matt
Guest





PostPosted: Sun Jan 11, 2004 2:46 pm    Post subject: Taille d'une structure Reply with quote



Bonjour,

un petit soucis :

#include <iostream>

struct Entete
{
char toto[5];
long tata;
};


int main(void)
{
Entete titi;

std::cout << "Taille d'un long : " << sizeof(long) << std::endl
// Ca me retourne 4 octets : OK
<< "Taille d'un char[5] : " << sizeof(char[5]) << std::endl
// Ca me retourne 5 octets : OK
<< "Taille de la structure : " << sizeof(titi) << std::endl;
// Ca me retourne 12 octets ???

return 0;
}

Pourquoi cette difference de taille et une autre question quand je veux
faire
titi.toto = "tyty";

Il me dit que titi.toto doit etre une l-value ???
pourquoi je ne peux affecter "tyty" a titi.toto ???

Ce que je veux faire c'est une structure contenant le format d'une entete
d'un fichier WAVE
et de pouvoir la modifier par la suite pour la mettre dans une fichier
(logique !!!).

Merci pour vos réponses

Matt...


Back to top
DomiPi
Guest





PostPosted: Sun Jan 11, 2004 3:27 pm    Post subject: Re: Taille d'une structure Reply with quote



"Matt" <mirabon_nospam (AT) free (DOT) fr> a écrit dans le message de
news:400161dc$0$19274$626a54ce (AT) news (DOT) free.fr...
Quote:
Bonjour,

un petit soucis :

#include
struct Entete
{
char toto[5];
long tata;
};


int main(void)
{
Entete titi;

std::cout << "Taille d'un long : " << sizeof(long) << std::endl
// Ca me retourne 4 octets : OK
"Taille d'un char[5] : " << sizeof(char[5]) << std::endl
// Ca me retourne 5 octets : OK
"Taille de la structure : " << sizeof(titi) << std::endl;
// Ca me retourne 12 octets ???

Si tu demandes au compilateur de compacter les structures; tu auras 9 pour
ta stucture. Si non par défaut les struct ne le sont pas, il y a des bytes
non utilisés entre les variables.

Quote:

return 0;
}

Pourquoi cette difference de taille et une autre question quand je veux
faire
titi.toto = "tyty";

Ca, c'est vouloir changer l'adresse de titi.toto et pas y copier "tyty".
Tu dois utiliser strcpy(titi.toto,"tyty"); titi.toto est un string en C,
c'est pas du C++ !!
Etudies comment traiter les pointeurs en C ainsi que les string ...

Quote:

Il me dit que titi.toto doit etre une l-value ???
pourquoi je ne peux affecter "tyty" a titi.toto ???

Même réponse ...

Quote:

Ce que je veux faire c'est une structure contenant le format d'une entete
d'un fichier WAVE
et de pouvoir la modifier par la suite pour la mettre dans une fichier
(logique !!!).

Merci pour vos réponses

Pas de quoi
Dominique

Quote:

Matt...





Back to top
Fabien LE LEZ
Guest





PostPosted: Sun Jan 11, 2004 3:43 pm    Post subject: Re: Taille d'une structure Reply with quote



On Sun, 11 Jan 2004 15:46:25 +0100, "Matt" <mirabon_nospam (AT) free (DOT) fr>
wrote:

Quote:
Pourquoi cette difference de taille

Question d'alignement. Sur un processeur 32 bits, les membres d'une
classe sont souvent alignés sur 4 octets, et le compilo rajoute des
"blancs" pour s'en assurer. Ainsi, une classe

struct Entete
{
char toto[5];
long tata;
};

sera considérée par le compilo comme :

struct Entete
{
char toto[5];
char padding [3]; // Membre "bidon", bien sûr inaccessible
long tata;
};

de façon à ce que l'espace mémoire occupé par ta tante commence à un 8
octets (ou un multiple de 4 en tout cas) du début de la classe.

Quote:
et une autre question quand je veux
faire
titi.toto = "tyty";

Il me dit que titi.toto doit etre une l-value ???

Oui.
Le code suivant :

char txt[]= "tyty";
titi.toto= txt;

est illégal, car tu essaies (en gros) de changer l'adresse du membre
de la classe. C'est comme si tu faisais :

long machin;
titi.tata= &machin;

J'imagine que ce que tu veux, c'est copier les 5 octets "tyty" dans le
membre, ce qui est totalement différent.

Dans un cas "normal", je t'aurais conseillé d'utiliser tout simplement
std::string à la place de char[], et le problème eût été réglé.
Toutefois...

Quote:
Ce que je veux faire c'est une structure contenant le format d'une entete
d'un fichier WAVE
et de pouvoir la modifier par la suite pour la mettre dans une fichier

.... dans ce cas précis, tu n'as pas le choix des armes.
Evidemment, tu pourrais encapsuler tout le bricolage à la Windows dans
une classe qui ferait tout le travail "sale" et dangereux en interne,
mais pour un petit programme dans un cadre éducatif, c'est peut-être
un peu lourd (Mais je ne suis pas catégorique sur ce point). Aussi te
conseillerai-je de jeter un oeuil sur les fonctions strncpy() et
memcpy(), en étudiant bien les différences entre les deux. Et en
n'oubliant pas que quand tu ponds tes propres classes, std::string est
largement plus adapté dans la plupart des cas (Dans les cas restants,
c'est std::vector<char> Wink ).

Au fait, il me semble qu'on n'emploie le mot "structure" qu'en C. En
C++, "struct" et "class" désignent tous les deux une classe ; la
différence entre les deux est que mettre "struct" à la place de
"class" rend l'héritage et les membres publics par défaut.

--
;-)

http://www.gotw.ca/gotw/063.htm
http://www.gotw.ca/gotw/067.htm#2

Back to top
Fabien LE LEZ
Guest





PostPosted: Sun Jan 11, 2004 3:45 pm    Post subject: Re: Taille d'une structure Reply with quote

On Sun, 11 Jan 2004 16:27:12 +0100, "DomiPi" <akuj0006 (AT) tiscali (DOT) be>
wrote:

Quote:
Tu dois utiliser strcpy(titi.toto,"tyty");

strncpy, plutôt, puisque la taille du tableau d'arrivée est fixe.
strcpy ne fait pas de contrôle sur la taille du tableau à copier.

--
;-)

http://www.gotw.ca/gotw/063.htm
http://www.gotw.ca/gotw/067.htm#2

Back to top
DINH Viêt Hoà
Guest





PostPosted: Sun Jan 11, 2004 4:41 pm    Post subject: Re: Taille d'une structure Reply with quote

DomiPi wrote :

Quote:
Si tu demandes au compilateur de compacter les structures; tu auras 9 pour
ta stucture. Si non par défaut les struct ne le sont pas, il y a des bytes
non utilisés entre les variables.

d'une manière générale, c'est une mauvaise méthode que de demander de
compacter les structures. Il vaut mieux faire la différence entre la
représentation en mémoire et la représentation sur fichier.

--
DINH V. Hoa,

etPan! - newsreader, mail user agent -- http://libetpan.sf.net/etpan


Back to top
Guillaume LEMAÎTRE
Guest





PostPosted: Sun Jan 11, 2004 6:04 pm    Post subject: Re: Taille d'une structure Reply with quote

Fabien LE LEZ wrote:
Quote:
On Sun, 11 Jan 2004 16:27:12 +0100, "DomiPi" wrote:


Tu dois utiliser strcpy(titi.toto,"tyty");


strncpy, plutôt, puisque la taille du tableau d'arrivée est fixe.
strcpy ne fait pas de contrôle sur la taille du tableau à copier.


mieux : memcpy, pour éviter de controler sans cesse que dans "tyty" il y
ait un ''


Back to top
Matt
Guest





PostPosted: Sun Jan 11, 2004 7:54 pm    Post subject: Re: Taille d'une structure Reply with quote

Bonsoir,

Merci pour vos reponses (rapides) ...

Matt...


Back to top
James Kanze
Guest





PostPosted: Sun Jan 11, 2004 9:25 pm    Post subject: Re: Taille d'une structure Reply with quote

"Matt" <mirabon_nospam (AT) free (DOT) fr> writes:

Quote:
un petit soucis :

#include <iostream

struct Entete
{
char toto[5];
long tata;
};

int main(void)
{
Entete titi;

std::cout << "Taille d'un long : " << sizeof(long) << std::endl
// Ca me retourne 4 octets : OK
"Taille d'un char[5] : " << sizeof(char[5]) << std::endl
// Ca me retourne 5 octets : OK
"Taille de la structure : " << sizeof(titi) << std::endl;
// Ca me retourne 12 octets ???

return 0;
}

Pourquoi cette difference de taille

Parce que le compilateur est libre de faire ce qu'il veut, et en
général, ne pas lui permettre d'introduire des octets de
rembourrage donnerait des performances inacceptables. Sur la plupart des
machines, accéder à un long qui n'est pas alignée sur une
adresse multiple de huit, par exemple, exigerait un appel d'une fonction
pour y accéder octet par octet. Même sur un Intel, qui permet de
tels accès, l'accès à une adresse non alignée est nettement
moins rapide.

Quote:
et une autre question quand je veux faire
titi.toto = "tyty";

Il me dit que titi.toto doit etre une l-value ???

C'est parce que les tableaux de type C (T[]) ne marche pas bien, ni en
C, ni en C++. En C++, on écrite std::string dans ce cas-ci, et ça
marche.

Quote:
pourquoi je ne peux affecter "tyty" a titi.toto ???

Parce que c'est interdit. Un tableau de type C, ce n'est pas un type
comme les autres.

Quote:
Ce que je veux faire c'est une structure contenant le format d'une
entete d'un fichier WAVE et de pouvoir la modifier par la suite pour
la mettre dans une fichier (logique !!!).

C'est un cas un peu spécial. Si j'ai bien compris, tu veux avoir un
struct qui se plaque sur un tableau de char pour implémenter un
format externs.

Formellement, la norme n'offre aucune solution, et il y a des machines
où c'est carrément impossible, du fait de la façon que
fonctionne le hardware. Mais sur des machines courrantes, tu peux le
faire, à condition que la struct ne contient que des char[]. Donc,
dans ton cas :

struct Entete
{
char toto[ 5 ];
unsigned char tata[ 4 /* ou 8 */ ] ;
} ;

std::vector< char > buffer;
buffer.resize( sizeof( Entete ) ) ;
Entete& entete = &buffer[ 0 ] ;
memcpy( entete.toto, leTotoQuilMeFaut, 5 ) ;
memcpy( entete.tata, leTataQuilMeFaut, 4 ) ;

À condition aussi, bien évidemment, que le format interne
corresponde bien au format externe. Ce qui est rarement le cas.

--
James Kanze mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93

Back to top
James Kanze
Guest





PostPosted: Sun Jan 11, 2004 9:27 pm    Post subject: Re: Taille d'une structure Reply with quote

"DomiPi" <akuj0006 (AT) tiscali (DOT) be> writes:

Quote:
"Matt" <mirabon_nospam (AT) free (DOT) fr> a écrit dans le message de
news:400161dc$0$19274$626a54ce (AT) news (DOT) free.fr...

un petit soucis :

#include
struct Entete
{
char toto[5];
long tata;
};

int main(void)
{
Entete titi;

std::cout << "Taille d'un long : " << sizeof(long) << std::endl
// Ca me retourne 4 octets : OK
"Taille d'un char[5] : " << sizeof(char[5]) << std::endl
// Ca me retourne 5 octets : OK
"Taille de la structure : " << sizeof(titi) << std::endl;
// Ca me retourne 12 octets ???

Si tu demandes au compilateur de compacter les structures; tu auras
9 pour ta stucture.

C'est bien, mais en général, les compilateurs ne les compactent
pas, et il n'y a pas souvent un moyen à leur démander de le faire.

Quote:
Si non par défaut les struct ne le sont pas, il y a des bytes non
utilisés entre les variables.

return 0;
}
Pourquoi cette difference de taille et une autre question quand je
veux faire

titi.toto = "tyty";

Ca, c'est vouloir changer l'adresse de titi.toto et pas y copier
"tyty". Tu dois utiliser strcpy(titi.toto,"tyty");

Et vive les core dumps.

--
James Kanze mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93

Back to top
James Kanze
Guest





PostPosted: Sun Jan 11, 2004 9:29 pm    Post subject: Re: Taille d'une structure Reply with quote

Guillaume LEMAÎTRE <zarmalala (AT) biniou (DOT) org> writes:

Quote:
Fabien LE LEZ wrote:
On Sun, 11 Jan 2004 16:27:12 +0100, "DomiPi" wrote:

Tu dois utiliser strcpy(titi.toto,"tyty");

strncpy, plutôt, puisque la taille du tableau d'arrivée est
fixe. strcpy ne fait pas de contrôle sur la taille du tableau
à copier.

mieux : memcpy, pour éviter de controler sans cesse que dans
"tyty" il y ait un ''

Et pour accéder au délà de la fin du tableau si la source
contient moins d'octets qu'il n'en faut.

La réponse de Fabien a l'avantage d'être correcte du point de vue
du langage. Reste à voir s'il convient au cahier de charges -- on ne
sait pas encore ce qu'on veut exactement.

--
James Kanze mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93

Back to top
Matt
Guest





PostPosted: Mon Jan 12, 2004 6:54 am    Post subject: Re: Taille d'une structure Reply with quote


Quote:
|> >>Tu dois utiliser strcpy(titi.toto,"tyty");

|> > strncpy, plutôt, puisque la taille du tableau d'arrivée est
|> > fixe. strcpy ne fait pas de contrôle sur la taille du tableau
|> > à copier.

|> mieux : memcpy, pour éviter de controler sans cesse que dans
|> "tyty" il y ait un ''

Et pour accéder au délà de la fin du tableau si la source
contient moins d'octets qu'il n'en faut.

La réponse de Fabien a l'avantage d'être correcte du point de vue
du langage. Reste à voir s'il convient au cahier de charges -- on ne
sait pas encore ce qu'on veut exactement.


Bonjour,

J'ai retenu la réponse de fabien strncpy qui est très bien.
En fait, ma structure est un format d'entête wave.
Je voulais réserver l'espace nécessaire en début de fichier avant de
mettre les échantillons et enfin rajouter dans l'entête les
renseignements
obtenus a la fin de l'enregistrement...(Taille fichier, taille
échantillons ...)
Puis toujours avec cette structure, récupérer les données pour en
faire une lecture.
Il y a des chaînes de caractères (toujours sur 4 octets),
des long et des short... mais j'ai toujours quelques soucis pour la
taille
de ma structure car elle doit faire une taille (44 octets) et ni plus ni
moins.

Matt...



Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Jan 12, 2004 12:03 pm    Post subject: Re: Taille d'une structure Reply with quote

"Matt" <mirabon_nospam (AT) free (DOT) fr> wrote

Quote:
|> >>Tu dois utiliser strcpy(titi.toto,"tyty");

|> > strncpy, plutôt, puisque la taille du tableau d'arrivée est
|> > fixe. strcpy ne fait pas de contrôle sur la taille du tableau
|> > à copier.

|> mieux : memcpy, pour éviter de controler sans cesse que dans
|> "tyty" il y ait un ''

Et pour accéder au délà de la fin du tableau si la source contient
moins d'octets qu'il n'en faut.

La réponse de Fabien a l'avantage d'être correcte du point de vue du
langage. Reste à voir s'il convient au cahier de charges -- on ne
sait pas encore ce qu'on veut exactement.

J'ai retenu la réponse de fabien strncpy qui est très bien.

En fait, ma structure est un format d'entête wave. Je voulais
réserver l'espace nécessaire en début de fichier avant de mettre
les échantillons et enfin rajouter dans l'entête les
renseignements obtenus a la fin de l'enregistrement...(Taille
fichier, taille échantillons ...) Puis toujours avec cette
structure, récupérer les données pour en faire une lecture.

Il y a des chaînes de caractères (toujours sur 4 octets), des long
et des short... mais j'ai toujours quelques soucis pour la taille
de ma structure car elle doit faire une taille (44 octets) et ni
plus ni moins.

Quand il s'agit d'écrire un nombre exact d'octets dans un fichier (ou
sur le reseau), la meilleur solution reste toujours à écrire tant
d'octets, comme des octets. Si on a une chaîne de caractères, par
exemple, on pourrait faire quelque chose du genre :

void
writeString( ostream& dest, std::string const& source, int count )
{
std::string::const_iterator
i = source.begin() ;
while ( count > 0 ) {
dest.put( i == source.end() ? '': *i ++ ) ;
count -- ;
}
}

Pour des types autres que les chaînes de caractères, le problème est
plus complex, parce que les formats des entiers ne sont pas identiques
sur toutes les machines. Dans la pratique, si tu sais que tu n'aurais
jamais à porter que sur des machines couramment répandues, tu peux
supposer que le format interne est complément à deux, ce qui est aussi
le format le plus courant pour des valeurs binaires dans des fichiers ou
sur le reseau. (En ce qui concerne les machines plus exotiques, il en
existe où même la taille des bytes n'est pas huit bits.) Tu n'aurais
donc plus qu'à t'occuper de la taille (combien d'octets) et de l'ordre
des octets. Pour un entier de 4 octets, par exemple :

void
write4ByteInt( ostream& dest, long value )
{
assert( value <= 2147483647 && value >= -2147483648 ) ;
dest.put( static_cast< char >( (value >> 24) & 0xff ) ;
dest.put( static_cast< char >( (value >> 16) & 0xff ) ;
dest.put( static_cast< char >( (value >> Cool & 0xff ) ;
dest.put( static_cast< char >( (value ) & 0xff ) ;
}

(Cet exemple sort les octets le poids forts d'abord, c-à-d dans l'ordre
Internet. On inverse l'ordre des écritures pour les sortir poids faibles
d'abord.)

N'oublie pas que dans des cas comme ceci, il faut que le fichier soit
ouvert en binaire.

Souvent, on veut formatter tout un enrégistrement en mémoire, afin de
pouvoir l'écrire d'un coup. Dans ce cas, on peut très bien se servir
d'un vector<char>, en remplaçant les dest.put() par des
dest.push_back(). Sinon, formatter vers un char[], au moyen de
ostrstream, marche bien aussi ; si tu dois formatter certains champs
(par exemple, sortir des nombres en texte), c'est la seule solution
valable.

Le seul problème avec cette méthode, c'est qu'il devient rapidement
pénible (et une source d'erreurs) de compter tout à la main. C'est en
fait bien plus facile à le laisser faire par le compilateur, en écrivant
quelque chose du genre :

struct Header
{
char field1[ 5 ] ;
char field2[ 4 ] ;
// ...
} ;

Selon la norme, rien n'y est garantie. Le compilateur a le droit d'y
insérer des octets supplémentaire de rembourrage ou bon lui semble. Dans
la pratique, en revanche, j'ai d'assez bonnes expériences avec ça à
condition que tous les champs de la struct soit des char[] (et que des
char[]). Pour utiliser cette technique, les règles suivantes s'imposent :

- Tout au début du programme, il faut un assert que la taille de la
struct est bien celui que tu veux.

- On insère toujours les valeurs comme ci-dessus. Pas de memcpy ou
d'autres (au moins qu'on fasse un memcpy d'un champs déjà formatté).
Pour les sorties formattées, c'est toujours possible à faire des
choses du genre :

Header h ;
ostrstream s( h.field2, sizeof( h.field2 ) ) ;
s << setw( sizeof( h.field2 ) ) << valeur ;

C'est une utilisation particulière de strstream ; on ne peut pas la
remplacer par stringstream.

Mais dans l'ensemble, la première méthode est plus sûre, même si c'est
un peu plus fastidieux à mettre en oeuvre.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Back to top
konroth
Guest





PostPosted: Thu Jan 15, 2004 1:21 pm    Post subject: Re: Taille d'une structure Reply with quote


Matt a écrit:
Quote:
Bonjour,

un petit soucis :

#include
struct Entete
{
char toto[5];
long tata;
};


int main(void)
{
Entete titi;

std::cout << "Taille d'un long : " << sizeof(long) << std::endl
// Ca me retourne 4 octets : OK
"Taille d'un char[5] : " << sizeof(char[5]) << std::endl
// Ca me retourne 5 octets : OK
"Taille de la structure : " << sizeof(titi) << std::endl;
// Ca me retourne 12 octets ???

return 0;
}

Pourquoi cette difference de taille et une autre question quand je veux
faire
titi.toto = "tyty";

Il me dit que titi.toto doit etre une l-value ???
pourquoi je ne peux affecter "tyty" a titi.toto ???

Ce que je veux faire c'est une structure contenant le format d'une entete
d'un fichier WAVE
et de pouvoir la modifier par la suite pour la mettre dans une fichier
(logique !!!).

Merci pour vos réponses

Matt...




---------------------------------------------------------------------------------------
on peux choisir dans les 'compiler options' les 'struct member alingement'.
Visual c++ 6 default c'est huit(Cool byte. Ca explique la "fausse" taille.

excusez mon francais
---------------------------------------------------------------------------------------



Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.