OVH Cloud OVH Cloud

Initialisation de structure

15 réponses
Avatar
Tutu
Bien le bonjour,

j'ai un leger soucis pour initialiser correctement une structure.

Voici le code:

typedef struct foo_s {
/* ces trois champs sont de meme longueur LENGHT1 */
char* un;
char* deux;
char* trois;
} foo_t;

typedef foo_t** bar_t;

typdef struct quux_s {
bar_t toto;
int tata;
int tutu;
...
} quux_t;

Je souhaite en fait initialiser une variable de type quux_t,
sachant que "un" "deux" et "trois" sont de longueur N, et que
toto est un tableau a deux dimensions, K et L (les valeurs ne sont
pas connues a la compilation, d'ou les pointeurs...).

j'ai pense a quelque chose dans ce gout-la :

void init_blah(quux_t* q, bar_t k, int i, int j, etc)
{
q->tata = i;
q->tutu = j;
init_bouh(&(k->toto), i, j);
}

et

void init_bouh(bar_t* b, int i; int j)
{
int x, y, z;
*b = malloc(i * sizeof(foo_t*));
for(x=0; x<i; ++x)
{
*b[x] = malloc(j * sizeof(foo_t));
for(y=0; y<j; y++)
{
*b[x][y].un = malloc(LENGTH1);
*b[x][y].deux = malloc(LENGTH1);
*b[x][y].trois = malloc(LENGTH1);
}
}
}

J'ai volontairement omis les verifications de retour de malloc().
Sur ce code, j'ai un segfault des l'allocation d'espace pour "un",
une idee ?


P.

5 réponses

1 2
Avatar
Richard Delorme
void
init_ensembles(ligne_t*** s,
unsigned int as,
unsigned int nensembles)
{
int i, j;
*s = malloc(as * sizeof(ligne_t*));
for(i=0; i<as; ++i)
{
(*s)[i]=malloc(nensembles * sizeof(ligne_t));
for(j=0; j<nensembles; ++j)
{
(*s)[i][j].policy=malloc(sizeof(char*));
(*s)[i][j].ligne=malloc(sizeof(char*));
(*s)[i][j].statut=malloc(sizeof(char*));


N'est-ce pas plutôt :
(*s)[i][j].policy=malloc(LONGUEUR_LIGNE);
(*s)[i][j].ligne=malloc(LONGUEUR_LIGNE);
(*s)[i][j].statut=malloc(LONGUEUR_LIGNE);
? Ou est-ce encore une erreur de recopiage ? ;-)

memset((*s)[i][j].policy, 0, (size_t)LONGUEUR_LIGNE);
memset((*s)[i][j].ligne, 0, (size_t)LONGUEUR_LIGNE);
memset((*s)[i][j].statut, MEMOIRE_CLEAN, (size_t)LONGUEUR_LIGNE);


--
Richard

Avatar
Régis Troadec
"Tutu" a écrit dans le message de
news:c547ic$2jak$

Salut,

[snip du reste]


data_t
acces_memoire (memoire_t* memoire,
char type_acces,
addresse_t addresse,
short taille,
data_t donnee)
{
unsigned int offset = 0;
unsigned int index = 0;
int i = 0;
unsigned int found = 0;
data_t ret = 0x00000000;

offset = (unsigned int) (addresse & OFFSET_MASK);
index = (unsigned int) ((addresse & INDEX_MASK) >> OFFSET_LEN);


Donc a l'appel dans le main, adresse est un adresse_t (c'est quoi ?) et tu
passes une constante entiere, 0x00000081

/* OFFSET_MASK, INDEX_MASK et OFFSET_LEN sont definis ailleurs ... */


Justement, ca serait utile que tu nous dises ce que c'est exactement


for(i=0; i<ASSOCIATIVITE-1; ++i)
{
/***************************************************/
/* SEGFAULT ICI */
/***************************************************/
found = MAX(memoire->ensembles[i][index].lru[offset],
memoire->ensembles[i+1][index].lru[offset]);


Je suppose que MAX est une macro, mais la n'est AMA pas le probleme.

Dans un premier temps, regarder memoire, puis ensembles.

Par exemple, avant ta boucle for :

Pour le debug, inclure <assert.h> pour utiliser assert(int expr) qui
t'affiche un joli message d'erreur explicite si expr est evaluee comme etant
nulle :

assert(memoire != NULL);
assert(memoire->ensemble != NULL);

Par ailleurs, tu controles ta boucle avec ce qu'il me semble etre une macro
(ASSOCIATIVITE) tandis qu'il y a un membre de memoire_t qui semble etre la
meme chose. Tu as passe en parametre des valeurs (avec assoc ( ASSOCIATIVITE) dans init_memoire et as dans init_ensembles) pour les
diverses allocations, ca m'a l'air correct, mais attention a la coherence.

Que valent i, index et offset ? N'accedes tu pas en dehors de la memoire
prevue pour ensembles ? Idem pour lru.

A propos, c'est quoi lru, il me semble que ensembles est un ligne_t** et
qu'un ligne_t n'a pas de membre de ce genre membres (type char* ligne,
policy et statut).

}

return EXIT_SUCCESS;
}


----------------------- fin toto.c ---------------------------------

----------------------- main.c -------------------------------------
/* inclusion des .h qui vont bien */

int main(void)
{
...
memoire_t* memoire = NULL;
ligne_t** lignes = NULL;
unsigned int longueur_ligne = LONGUEUR_LIGNE;
unsigned int assoc = ASSOCIATIVITE;
unsigned int nb_lignes = NB_LIGNES;
init_memoire(memoire, lignes, assoc, nb_lignes, longueur_ligne);
acces_memoire(memoire, ECRITURE, 0x00000081, 4, 0x00000001);


Cf. remarques acces_memoire.

...
}



Regis

Avatar
Régis Troadec
"Richard Delorme" a écrit dans le message de
news:4075ccac$0$292$
void
init_ensembles(ligne_t*** s,
unsigned int as,
unsigned int nensembles)
{
int i, j;
*s = malloc(as * sizeof(ligne_t*));
for(i=0; i<as; ++i)
{
(*s)[i]=malloc(nensembles * sizeof(ligne_t));
for(j=0; j<nensembles; ++j)
{
(*s)[i][j].policy=malloc(sizeof(char*));
(*s)[i][j].ligne=malloc(sizeof(char*));
(*s)[i][j].statut=malloc(sizeof(char*));


N'est-ce pas plutôt :
(*s)[i][j].policy=malloc(LONGUEUR_LIGNE);
(*s)[i][j].ligne=malloc(LONGUEUR_LIGNE);
(*s)[i][j].statut=malloc(LONGUEUR_LIGNE);
? Ou est-ce encore une erreur de recopiage ? ;-)


Il a bien precise au debut de son post que c'etait un copier-coller.
Je crois bien que tu tiens la solution, ca m'a achappe alors que je viens de
regarder son code pendant 10min, et je lui ai par consequent poste des
remarques peut-etre compeltement inutiles qui ne vont faire que
l'embrouiller un peu plus :)

regis

--
Richard



Avatar
Yves ROMAN

Bon, etant donne que je me plante a chaque recopiage, je vais faire un c/c
des fonctions/types/structures incriminees.

------------------------ toto.h -----------------------
/* garde sur TOTO_H + inclusions des .h qui vont bien*/

[...]


typedef struct memoire_s {

ligne_t** ensemble;
unsigned char associativite;
unsigned char nb_ensembles;
unsigned short longueur_ligne;

} memoire_t;

[...]

--------------------------- fin toto.h --------------------

--------------------------- toto.c ------------------------
/* inclusion des .h qui vont bien */

[...]


void
init_memoire(memoire_t* memoire,
ligne_t** ensembles,
unsigned int as,
unsigned int nensembles,
unsigned short longueur_ligne)
{
memoire=malloc(sizeof(memoire_t));
memoire->associativite = as;
memoire->nensembles = nensembles;
memoire->longueur_ligne = longueur_ligne;
init_ensembles(&(memoire->ensembles), as, nensembles);
(void)fprintf(stderr, "as=%d; nensembles=%d, linesize=%dn",
memoire->associativite,
memoire->nensembles,
memoire->longueur_ligne);
}


[...]

----------------------- fin toto.c ---------------------------------

----------------------- main.c -------------------------------------
/* inclusion des .h qui vont bien */

int main(void)
{
...
memoire_t* memoire = NULL;
ligne_t** lignes = NULL;
unsigned int longueur_ligne = LONGUEUR_LIGNE;
unsigned int assoc = ASSOCIATIVITE;
unsigned int nb_lignes = NB_LIGNES;
init_memoire(memoire, lignes, assoc, nb_lignes, longueur_ligne);


Et, surprise !, ici, memoire vaut encore NULL !!!!

le memoire de main n'a pas pu être modifié par init_memoire() car on ne lui
a pas passé son adresse

acces_memoire(memoire, ECRITURE, 0x00000081, 4, 0x00000001);
...
}

----------------------- fin main.c ----------------------------------



2 Options :
- soit allouer memoire dans main
memoire_t memoire ;
init_memoire(&memoire,...)
et dans init_memoire() ne pas faire de malloc()

- soit laisser init_memoire() l'allouer, mais il faut alors luis passer un
memoire_t**
memoire_t *memoire ;
init_memoire(&memoire,...)

Avatar
Marc Boyer
Éric Lévénez wrote:
Le 8/04/04 16:23, dans <c53n96$29ks$, « Tutu »
a écrit :
Le fait d'avoir masqué le pointeur par un type intermédiaire oblige à
utiliser foo_t pour avoir la taille et bar_t pour savoir où le mettre. Pas
joli d'utiliser ainsi 2 types.


En fait, je suis moins à cheval sur la règle "ne pas masquer
les pointeurs", mais si on fait cela, il faut aller jusqu'au
bout et fournir les fonctions de construction, destruction
et copie qui vont avec le type.

Si on masque, on dit à l'utilisateur de ne pas s'en soucier,
donc c'est un truc genre TAD/POO et on fournit tout ce qui
va avec.

Marc Boyer
--
La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...

1 2