[C] Initialisation de chaînes de caractères

Salut,
je me demandais quelle pouvait être la meilleure approche lorsque l’on initialise des [mono]char*[/mono].

J’ai une structure qui contient des [mono]int[/mono], [mono]double[/mono] et [mono]char*[/mono].
Lorsque j’ai besoin de cette structure, j’utilise un pointeur vers ce type de structure auquel la mémoire nécessaire est allouée. Les variables sont initialisées à 0 (int), 0. (double) et NULL (char*).

Question:
Quelle est la meilleure manière d’initialiser un [mono]char*[/mono]? Sachant que l’utilisateur n’est pas obligé de remplir toutes les chaînes (beaucoup resteront vides).

/* Exemple de constructeur. */
ma_struct* ma_var;

ma_var = malloc(sizeof(ma_struct));

ma_var->chaine1 = NULL;
/* OU BIEN */
ma_var->chaine2 = malloc(sizeof(char));
strcpy(s2,"");/* Qui va écrire '\0' dans s2. */

Pour l’instant, j’utilise la manière 1 et je fais attention à ce que mes chaînes soient bien remplies à un moment (au moins avec ‘\0’) sinon les free(s1) me sortiront un seg fault.
D’où l’idée de faire l’allocation dans le constructeur comme pour s2.
Vos avis?

Un char* est un pointeur. Le standard de C99 indique qu’il faut initialiser les pointeurs par NULL (sans distinction pour les char*).

En plus du standard, ça semble logique. Pourquoi s’enquiquinner à allouer de la mémoire pour y stocker une initialisation qui ne sera jamais utilisée, avec le risque d’oublier de libérer la mémoire au moment où tu replaces ta chaîne de caractères par du contenu utile ?

Pour éviter les erreurs de segmentation au moment de la libération de la mémoire, la méthode la plus propre est certainement de tester si ton pointeur est différent de NULL. Ici aussi, ça évite de gaspiller de la mémoire pour stocker seulement du contenu d’initialisation.

D’ailleurs, il me semble que l’optimisation de gcc supprime les pointeurs qui sont créés, intialisés, modifiés, puis libérés sans être lus. (Ne pas comprendre par là que je confonds la compilation avec l’exécution. C’est juste que les optimisations de gcc sont proches des best practices.)

J’espère que ça répond à ta question.

C’est parfait merci!

Je n’ai donc pas touché à mes constructeurs mais j’ai rajouté des vérifications (!= NULL) lorsque la valeur du pointeur n’est pas garantie: dans les destructeurs par exemple.

C’était l’occasion de relire mon code et de corriger qqs bugs dont certains dûs à l’idée tenace que les int sont automatiquement = 0. :075

Mon programme ressemble à un tableur dont les cases ne sont pas forcément remplies par l’utilisateur.
Dans ce cas, elle finissent avec ‘\0’ à cause des méthodes GTK+ ou des miennes. Mais cela ne se fait pas lors de l’initialisation.

C’est logique et ça structure mieux le code.
Merci!