Quand faire malloc ou pas en C dans 1 struct

Lucille88 -  
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjour, j'ai un conseil à demander sur le programme suivant:

void f(struct chien *p_c,char*modele,int*p_pattes)
{
p_c->modele=malloc(sizeof(strlen(modele)+1));
strcpy(p_c->modele,modele);
p_c->pattes=*p_pattes;
}

#include <stdio.h>


struct chien{
char*modele;
int pattes;
};

void f(struct chien *p_c, char * modele, int * p_pattes)
{
p_c->modele=modele;
p_c->pattes=*p_pattes;
}

int main(void)
{

int i;
struct chien c1;
struct chien c2;

i=3;
f(&c1,"labrador",&i);
i=8;

f(&c2,"caniche",&i);

printf("Ce %s a %d pattes\n",c1.modele,c1.pattes);
printf("Ce %s a %d pattes\n",c2.modele,c2.pattes);

return 0;
}

En fait il compile et il exécute et je ne comprends pas pourquoi car on alloue pas de mémoire pour la chaîne de caractères modèle.
Moi j'aurais écrit:

void f(struct chien *p_c,char*modele,int*p_pattes)
{
p_c->modele=malloc(sizeof(strlen(modele)+1));
strcpy(p_c->modele,modele);
p_c->pattes=*p_pattes;
}

pourquoi les deux écritures sont correctes? J'aimerais bien avoir une explication sur ce problème.

Merci d'avance pour vos réponses.

5 réponses

bizu53 Messages postés 1274 Date d'inscription   Statut Membre Dernière intervention   861
 
il me semble que c'est parce que quand tu appelles ta fonction avec directement en paramètre "labrador" par exemple, il doit bien allouer la mémoire nécessaire quelque part. Et tu places l'adresse du premier caractère dans ta structure ... Je pense que c'est pour ça que ça marche dans ce cas précis.
1
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Non il faut allouer, il n'y a pas de soucis.
Des fois ça marche, car tout simplement, ça récrit sur des informations pas importants dans le heap. Donc il n'y a pas de problème. Mais, dans certain cas ça ne marchera pas.
Donc, toujours alloué un char* ;)
1
Lucille88
 
En fait le véritable programme était:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct chien{
char*modele;
int pattes;
};

void f(struct chien *p_c, char * modele, int * p_pattes)
{
p_c->modele=modele;
p_c->pattes=*p_pattes;
}

int main(void)
{
char ch[10];
int i;
struct chien c1;
struct chien c2;
strcpy(ch,"labrador");
i=3;
f(&c1,ch,&i);
i=8;
strcpy(ch,"caniche");
f(&c2,ch,&i);

printf("Ce %s a %d pattes\n",c1.modele,c1.pattes);
printf("Ce %s a %d pattes\n",c2.modele,c2.pattes);

return 0;
}

mais je suppose que les explications valent aussi dans ce cas.

Par contre je me demandais quand fiddy dit "toujours alloué un char*"
Quand on écrit par exemple
char * ch1;
ch1="OULA";
Là il n'y a pas besoin de faire de malloc, non?
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
char * ch1;
ch1="OULA";

Besoin d'un malloc, sinon ça se ramène dans ton cas. Ca peut marcher, si ça ne récrit pas sur des données vitales dans la pile. On itialise toujours une chaine avec strcpy ou les équivalents jamais avec le signe "=" sauf à la déclaration.

Par contre
char * ch1="OULA";

Pas besoin d'allocation, le compilateur le fera à ta place ;)
0
Lucille88
 
Merci!
Juste une dernière question (dsl je suis têtue...) mais je voudrais être sûre d'avoir compris:
dans ce ptit programme(donné par le prof donc correct), il n'y a pas de malloc et pourtant s1.ch1=BB; n'est pas une déclaration.

#include <stdio.h>
#include <string.h>

#define MAX 10

struct S {
char * ch1;
char ch2[MAX];
};

int main(void)
{
struct S s1;

s1.ch1="OULA";
strcpy(s1.ch2,"OULA");
s1.ch2[0]='A';
s1.ch1="BB";

printf("%s %s\n",s1.ch1,s1.ch2);
return (0);
}
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Non tu as raison de poser tes questions ;)
Oui le programme de ton prof est tout à fait correct, car il s'agit d'une chaîne constante "OULA". Donc pas de soucis pour le compilateur. En revanche, le comportement de ton programme sera indéfini si tu modifies cette chaîne car cela est non prévu par la norme ANSI.
0