OVH Cloud OVH Cloud

Contigüité memoire ?

43 réponses
Avatar
May
Bonjour,

J'utilise une classe de base tres simple :

struct donne
{
double Int;
double Ext;
double IntExt;
}

puis un tableau aloué statiquement pour le moment

donne Tab[1024];

Ma question est assez simple, dans quel ordre en memoire, sont les données ?
Est-ce que je peux faire un truc du genre :

double *ptr=&Tab[0].Int;
for (int i=0;i<256;i++,ptr+=3)
{
*ptr=1.0;
}

Afin d'initialiser tous les champ Int de toutes les classes du tableau ?
Et si oui est-ce que ca reste valable si je fait un tableau dynamique à la C
(new/delete) ? ou avec std::vector<donne> ?

Merci
May

10 réponses

1 2 3 4 5
Avatar
Christophe Lephay
"May" a écrit dans le message de
news:bkp685$o12$
struct donne
{
double Int;
double Ext;
double IntExt;
}

donne Tab[1024];

Ma question est assez simple, dans quel ordre en memoire, sont les données
?

Est-ce que je peux faire un truc du genre :

double *ptr=&Tab[0].Int;
for (int i=0;i<256;i++,ptr+=3)
{
*ptr=1.0;
}



Non, tu ne peux pas. tout d'abords, rien ne te dit que les doubles ont une
taille de 3 octets. Si tu augmentes ton pointeur avec ptr+=sizeof( double ),
tu auras la bonne taille, mais tu as toujours les problème de
padding/alignement mémoire qui font que &Tab[ 1 ] == &Tab[ 0 ] +
3*sizeof( double ) n'est pas garantis.

Chris

Avatar
Christophe Lephay
"Christophe Lephay" a écrit dans le message
de news:bkp8ja$dg0$
"May" a écrit dans le message de
news:bkp685$o12$
struct donne
{
double Int;
double Ext;
double IntExt;
}

donne Tab[1024];

Ma question est assez simple, dans quel ordre en memoire, sont les
données


?
Est-ce que je peux faire un truc du genre :

double *ptr=&Tab[0].Int;
for (int i=0;i<256;i++,ptr+=3)
{
*ptr=1.0;
}



Non, tu ne peux pas. tout d'abords, rien ne te dit que les doubles ont une
taille de 3 octets. Si tu augmentes ton pointeur avec ptr+=sizeof(
double ),

tu auras la bonne taille,


Hum, j'ai dit une connerie vu que ptr est un pointeur sur double. Mais tu ne
peux toujours pas ;)

Chris


Avatar
Samuel Krempp
le Tuesday 23 September 2003 12:57, écrivit :

Hum, j'ai dit une connerie vu que ptr est un pointeur sur double. Mais tu
ne peux toujours pas ;)


si sizeof(donne)=n * sizeof(double) (et c'est très probablement le cas sur
une machine normale, avec n=3), je crois que le code est correct :

double *ptr=&Tab[0].Int;
for (int i=0;i<256;i++,ptr+=n)
[..]

et sinon il n'y a qu'à ajouter dans le struct donne un char[] de la taille
qu'il faut pour que sizeof(donne) soit un multiple de sizeof(double).
(ou bien à incrémenter ptr en tant que void *, +=sizeof(donne), etc..)

ceci-dit, je n'ai jamais eu à voir ce qui est assuré en C++ pour ces
histoires d'alingmeent, je ne mettrais pas ma main au feu que ce que j'ai
dit est correct.
--
Sam

Avatar
Gabriel Dos Reis
"May" writes:

| Bonjour,
|
| J'utilise une classe de base tres simple :
|
| struct donne
| {
| double Int;
| double Ext;
| double IntExt;
| }
|
| puis un tableau aloué statiquement pour le moment
|
| donne Tab[1024];
|
| Ma question est assez simple, dans quel ordre en memoire, sont les données ?

peu importe.

| Est-ce que je peux faire un truc du genre :

Pas exactement.

|
| double *ptr=&Tab[0].Int;
| for (int i=0;i<256;i++,ptr+=3)

for (int i = 0; i < 256; ++i, ptr += sizeof (donne))

Note le sizeof.

| {
| *ptr=1.0;
| }
|
| Afin d'initialiser tous les champ Int de toutes les classes du tableau ?

then say what you mean

for (int i = 0; i < 256; ++i)
Tab[i].Int = 1.0;

Cela me paraît dire clairement ce que tu as énoncé ci-haut.

| Et si oui est-ce que ca reste valable si je fait un tableau dynamique à la C
| (new/delete) ? ou avec std::vector<donne> ?

Oui.

Mais qu'en est-il des autres données ?


std::vector<donne> tab(1024);
const donne init = { 1.0 };
std::fill_n(&tab[0], 256, init);

(on peut envisager d'écrire dans quelque temps
std::fill_n(&tab[0], 256, (donne){ 1.0 })

-- Gaby
Avatar
Gabriel Dos Reis
Samuel Krempp writes:

| le Tuesday 23 September 2003 12:57, écrivit :
|
| > Hum, j'ai dit une connerie vu que ptr est un pointeur sur double. Mais tu
| > ne peux toujours pas ;)
|
| si sizeof(donne)=n * sizeof(double) (et c'est très probablement le cas sur
| une machine normale, avec n=3), je crois que le code est correct :

néanmoins, qu'apporte cette hypothèse non portable -- elle ne rend
certainement pas le code lisible ; alors il doit y avoir une autre raison.

|
| double *ptr=&Tab[0].Int;
| for (int i=0;i<256;i++,ptr+=n)
| [..]
|
| et sinon il n'y a qu'à ajouter dans le struct donne un char[] de la taille
| qu'il faut pour que sizeof(donne) soit un multiple de sizeof(double).
| (ou bien à incrémenter ptr en tant que void *, +=sizeof(donne), etc..)

ahem. Pourquoi faire simple si on peut faire compliquer, hein ?

-- Gaby
Avatar
Christophe Lephay
"Gabriel Dos Reis" a écrit dans le message de
news:
"Christophe Lephay" writes:

| "May" a écrit dans le message de
| news:bkp685$o12$
| > struct donne
| > {
| > double Int;
| > double Ext;
| > double IntExt;
| > }
| >
| > donne Tab[1024];
| >
| > Ma question est assez simple, dans quel ordre en memoire, sont les
données

| ?
| > Est-ce que je peux faire un truc du genre :
| >
| > double *ptr=&Tab[0].Int;
| > for (int i=0;i<256;i++,ptr+=3)
| > {
| > *ptr=1.0;
| > }
| >
|
| Non, tu ne peux pas. tout d'abords, rien ne te dit que les doubles ont
une

| taille de 3 octets.

Pourquoi 3 octets ?

| Si tu augmentes ton pointeur avec ptr+=sizeof( double ),
| tu auras la bonne taille,

pour quelles raisons ?


Oui, j'avais dit une connerie (j'avais pas enregistré que ptr était un
pointeur sur double) - je suis souvent sujet à ce genre de confusions au
réveil quand je n'ai pas encore bu mon café (après aussi, mais moins)...

Chris

Avatar
Samuel Krempp
le Tuesday 23 September 2003 13:59, écrivit :

| double *ptr=&Tab[0].Int;
| for (int i=0;i<256;i++,ptr+=3)

for (int i = 0; i < 256; ++i, ptr += sizeof (donne))


mais là je pense que tu as oublié de déclarer ptr comme tu le veux au
préalable :
void * ptr
(et il faut faire des casts dans la boucle)

--
Sam

Avatar
Gabriel Dos Reis
Samuel Krempp writes:

| le Tuesday 23 September 2003 13:59, écrivit :
|
| > | double *ptr=&Tab[0].Int;
| > | for (int i=0;i<256;i++,ptr+=3)
| >
| > for (int i = 0; i < 256; ++i, ptr += sizeof (donne))
|
| mais là je pense que tu as oublié de déclarer ptr comme tu le veux au
| préalable :
| void * ptr
| (et il faut faire des casts dans la boucle)

Non. Je n'ai rien oublié. En fait, déclarer ptr de type « void* » rend
l'arithmétique invalide.

-- Gaby
Avatar
Christophe Lephay
"Gabriel Dos Reis" a écrit dans le message de
news:
"Christophe Lephay" writes:
| Que se passe-t-il avec un
| tableau de char si chaque adresse doit être alignée, par exemple, sur un
| multiple de 4 ? sizeof( char ) renverra-t-il 4 (au moins) ?

sizeof(char), par définition, vaut toujours 1.


Mais dans ce cas, comment peut-on avoir, avec char tab[ N ], &tab[
0 ]+sizeof( char ) == &tab[ 1 ] si chaque élément doit être aligné sur un
multiple de 4 ?

A moins que, avec char * ptr, ++ptr ne soit pas équivallent à ptr + sizeof( char ) dans le cas où on a des contraintes d'alignement ?

Chris

Avatar
adebaene
"May" wrote in message news:<bkp685$o12$...
Bonjour,

J'utilise une classe de base tres simple :

struct donne
{
double Int;
double Ext;
double IntExt;
}

puis un tableau aloué statiquement pour le moment

donne Tab[1024];

Ma question est assez simple, dans quel ordre en memoire, sont les données ?
Est-ce que je peux faire un truc du genre :

double *ptr=&Tab[0].Int;
for (int i=0;i<256;i++,ptr+=3)
{
*ptr=1.0;
}

Afin d'initialiser tous les champ Int de toutes les classes du tableau ?


Non, car tu n'as aucune garantie que sizeof(donne)==3; Sur un système
32 bits par exemple, ce ne serait pas étonnant que sizeof(donne)==4;

Tu peux faire :

double *ptr=&Tab[0].Int;
for (int i=0;i<256;i++,ptr+=sizeof(donne))
{
*ptr=1.0;
}

Mais pourquoi ne pas faire plus simple - et surtout plus lisible ? :
donne* ptr=Tab;
for (int i=0;i<256;i++,ptr++)
{
ptr->Int=1.0;
}

Et si oui est-ce que ca reste valable si je fait un tableau dynamique à la C
(new/delete) ? ou avec std::vector<donne> ?
Oui : Le tableaux alloués dynamiquement et les vector sont contigus

(pour les vectors, ce n'est pas encore frmellement le ca, mais on peut
faire comme si.)

Arnaud

1 2 3 4 5