Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Pb malloc realloc avec des tableaux de structures

13 réponses
Avatar
David Roman CESR
typedef struct {
char Key[13];
int Nb;
uint *List;
} List

ListTri **Ti_Se;

memset(Ti_Se,NULL,nEltsMax*sizeof(ListTri));


if (Ti_Se[0]==NULL) {

Ti_Se[0]=(ListTri *) malloc(sizeof(ListTri));
sprintf(Ti_Se[0]->Key,"%6.6i%6.6i",1234546,1234546);
Ti_Se[0]->Nb=101;

Ti_Se[0]->List=(uint *) malloc(sizeof(uint));
Ti_Se[0]->List[0]=20;

Ti_Se[0]->List=(uint *) realloc(Ti_Se[0]->List,2*sizeof(uint));
Ti_Se[0]->List[1]=30;

printf("AAA %i %s %i
%i\n",Ti_Se[0]->Nb,Ti_Se[0]->Key,Ti_Se[0]->List[0],Ti_Se[0]->List[1]);
}



Mon code est visiblement faux (pas pour moi sinon je poserai pas la
question)
Lorsque je j'etends la zone memoire du champs List de la structure,
j'ecrase
la valeur initiale du champ.

Que faut il ecrit pour que ce soit bon ???

3 réponses

1 2
Avatar
David Roman
HalfWolf wrote:

David Roman CESR wrote in message news:...
Je suis un bleu en C, mais avec tous le respect que je dois a un maitre du
C
je voudrais te faire remaquer que
sprintf(Ti_Se[0]->Key,"%6.6i%6.6i",1234546,1234546);
a pour resultat la chaine suivante '123456123456' soit 12 caracteres + le
caractere de fin
ce qui fait bien 13 caracteres au total. SI SI essayes le tu verras par toi
meme.


sprintf(Ti_Se[0]->Key,"%6.6i%6.6i",1234546,1234546);
a pour resultat la chaine suivante '12345461234546' soit 14 caracteres
+ le caractere de fin ce qui fait 15 caracteres au total.
SI SI essayes le tu verras par toi meme.

Je vais même plus loin, je te propose un programme de test :

# include <stdio.h>

int main(void)
{
int nbCharWritten;

nbCharWritten = printf("%6.6i%6.6i",1234546,1234546);
printf("n%d char writtenn", nbCharWritten);

return 0;
}

ce qui donne :

12345461234546
14 char written

En effet, %6.6i te garantit d'afficher AU MOINS 6 caractères pour ta
valeur. 1234546 en fait 7.

Certes ça ne fait pas 29, mais en attendant tu as quand même faux.
Manipuler l'ironie fasse à quelqu'un qui te répond pour t'aider alors
que, tu le dis toi-même, tu es un bleu en C, je trouve ça plutôt
irrespectueux.

HalfWolf, qui n'est pas content


Autant pour moi => 1234546 il y un 4 en trop, Me suis fourre en tapant mon exemple.
Mille excuses plates ......


Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', David Roman CESR wrote:

Est ce que la je suis bon pour obtenir mon diplome de programmeur C ????
Merci de ppour cos remarque.


Tires en les conclusions toi même. Voici un corrigé (-ed-):

#include <stdio.h>
/* -ed- Pas standard. Remplace
#include <malloc.h>
*/
#include <stdlib.h>

/* -ed- Pas utilise. Supprime
#include <errno.h>
*/
/* -ed- Pas standard. Supprime
#include <sys/types.h>
*/

/* -ed- Identificateur ambigu. Ameliore
typedef unsigned short int ushort;
*/
/* -ed- Identificateur non utilise, uint, non defini. Remplace
typedef unsigned short ushort;
*/
typedef unsigned uint;

/* -ed- Ajoute (memset)
*/
#include <string.h>

/* -ed- Ajoute (UINT_MAX)
*/
#include <limits.h>

typedef struct
{
char Key[13];
int Nb;
uint *List;
}
ListTri;

int main (void)
{

/* -ed- 'i' et 'j' non utilises : supprimes
int i, j;
*/
/* -ed- non utilise : supprime
char Key[13];
*/

ListTri **Ti_Se;

/* Allocation de 10 pointeurs vers des structures ListTri */
/* -ed- Je ne suis pas sur que le type soit bon.
Je prefere utiliser l'objet dont je suis sur.
Ti_Se = malloc (10 * sizeof (ListTri *));
*/
Ti_Se = malloc (10 * sizeof *Ti_Se);

if (Ti_Se == NULL)
{
/* -ed- Les caractŠres accentues ne sont pas portables
printf ("Erreur d'allocation mémoire !!!n");
*/
printf ("Erreur d'allocation memoire !!!n");
/* -ed- '1' n'est pas une valeur portable pour exit().
exit (1);
*/
exit (EXIT_FAILURE);
}

/* Initialise les pointeurs a 0 sizeof(NULL)=sizeof(ListTri *)=4 */
/* J'initialise les pointeurs et non pas les structures (remarque pour */
/* Bertrand) */
/* -ed- L'usage de 'memset(,0,)' n'est pas portable pour les pointeurs.
'NULL' ne peut pas servir a initialiser un 'int'
memset (Ti_Se, NULL, 10 * sizeof (ListTri *));
*/
{
size_t i;

for (i = 0; i < 10; i++)
{
Ti_Se[i] = NULL;
}
}

/* Allocation pour un element du tableau vers un structure ListTri */
/* -ed- Je ne suis pas sur que le type soit bon.
Je prefere utiliser l'objet dont je suis sur.
Ti_Se[1] = malloc (sizeof (ListTri));
*/
Ti_Se[1] = malloc (sizeof *Ti_Se[1]);
if (Ti_Se[1] == NULL)
{
printf ("Erreur d'allocation memoire !!!n");
exit (EXIT_FAILURE);
}

/* -ed- Il est conseille d'initialiser proprement la structure
nouvellement allouee
*/
{
static const ListTri z {
{0}
};
*Ti_Se[1] = z;
}

/* Renseignement de la structure */
/* -ed- Les constantes '1234546' sont de type 'long'.
"%i" attend un type 'int' et non un 'long'
'&Ti_Se[1]->Key[0]' est une facon compliquee d'ecrire
'Ti_Se[1]->Key + 0' ou 'Ti_Se[1]->Key'
La valeur des constan,tes est probablement '123456' et non '1234546'
sprintf (&Ti_Se[1]->Key[0], "%6.6i%6.6i", 1234546, 1234546);
*/

sprintf (Ti_Se[1]->Key, "%6.6li%6.6li", 123456L, 123456L);

Ti_Se[1]->Nb = 1;
/* -ed- Je ne suis pas sur que le type soit bon.
Je prefere utiliser l'objet dont je suis sur.
Ti_Se[1]->List = malloc (sizeof (uint));
*/
Ti_Se[1]->List = malloc (sizeof *Ti_Se[1]->List);

if (Ti_Se[1]->List == NULL)
{
printf ("Erreur d'allocation memoire !!!n");
exit (EXIT_FAILURE);
}
Ti_Se[1]->List[0] = 20;


printf ("Ti_Se[1]->Key =%sn", Ti_Se[1]->Key);
printf ("Ti_Se[1]->Nb =%in", Ti_Se[1]->Nb);
/* -ed- Le type attendu par "%i" est 'int' et non 'unsigned int'
printf ("Ti_Se[1]->List[0]=%in", Ti_Se[1]->List[0]);
*/
printf ("Ti_Se[1]->List[0]=%un", Ti_Se[1]->List[0]);
printf ("n");

/* Ajoute 2 elements dans le champ list */

/* -ed- realloc() peut echouer. Lire la FAQ a ce sujet */
Ti_Se[1]->List = realloc (Ti_Se[1]->List, 3 * sizeof *Ti_Se[1]->List);
if (Ti_Se[1]->List == NULL)
{
printf ("Erreur d'allocation memoire !!!n");
exit (EXIT_FAILURE);
}

Ti_Se[1]->Nb = 3;
Ti_Se[1]->List[1] = 30;

/* -ed- Un test aux limites permet un bon decrassage...'
Ti_Se[1]->List[2] = 40;
*/
Ti_Se[1]->List[2] = UINT_MAX;

printf ("Ti_Se[1]->Key =%sn", Ti_Se[1]->Key);
printf ("Ti_Se[1]->Nb =%in", Ti_Se[1]->Nb);
printf ("Ti_Se[1]->List[0]=%un", Ti_Se[1]->List[0]);
printf ("Ti_Se[1]->List[1]=%un", Ti_Se[1]->List[1]);
printf ("Ti_Se[1]->List[2]=%un", Ti_Se[1]->List[2]);
printf ("n");

/* -ed- Manque le retour (obligatoire en C90) */
return 0;
}


/*
Test avec Borland C 3.1 (Intel 16-bit)

Ti_Se[1]->Key 3456123456
Ti_Se[1]->Nb =1
Ti_Se[1]->List[0]

Ti_Se[1]->Key 3456123456
Ti_Se[1]->Nb =3
Ti_Se[1]->List[0]
Ti_Se[1]->List[1]0
Ti_Se[1]->List[2]e535

*/

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Bertrand Mollinier Toublet
David Roman wrote:
HalfWolf wrote:
David Roman CESR wrote in message news:...

Je suis un bleu en C, mais avec tous le respect que je dois a un maitre du
C je voudrais te faire remaquer que
sprintf(Ti_Se[0]->Key,"%6.6i%6.6i",1234546,1234546);
a pour resultat la chaine suivante '123456123456' soit 12 caracteres + le
caractere de fin
ce qui fait bien 13 caracteres au total. SI SI essayes le tu verras par toi
meme.


sprintf(Ti_Se[0]->Key,"%6.6i%6.6i",1234546,1234546);
a pour resultat la chaine suivante '12345461234546' soit 14 caracteres
+ le caractere de fin ce qui fait 15 caracteres au total.
SI SI essayes le tu verras par toi meme.

Certes ça ne fait pas 29, mais en attendant tu as quand même faux.
Manipuler l'ironie fasse à quelqu'un qui te répond pour t'aider alors
que, tu le dis toi-même, tu es un bleu en C, je trouve ça plutôt
irrespectueux.



Autant pour moi => 1234546 il y un 4 en trop, Me suis fourre en tapant mon exemple.
Mille excuses plates ......

Pas de probleme, je m'etais plante aussi (sur la signification du .6).

Notons au passage, que a force de contribuer, on gagne de la confiance
en soi, et on finit par manquer de retenue... Mea culpa.

--
Bertrand Mollinier Toublet
"Reality exists" - Richard Heathfield, 1 July 2003



1 2