Renvoyer une chaîne depuis une fonction C

J’ai un code simple.

#define MY_STRING "Ssortingng example" char* ssortingng_return_function() { return MY_STRING; } 

Le code ci-dessus fonctionne mais je ne sais pas comment. Je pense que ssortingng_return_function () renvoie une adresse locale, qui serait libérée une fois la fonction terminée.

Non, ce n’est pas comme ça que ça marche.

Les littéraux de chaîne sont stockés dans une mémoire qui persiste tant que le programme est exécuté. La fonction renvoie donc simplement un pointeur sur la constante de chaîne.

Il n’y a pas de création / initialisation de chaîne en cours d’exécution, aucun caractère n’est copié. Il ne fait que renvoyer un pointeur; le code machine de la fonction ne contient probablement que quelques instructions.

Par exemple, voici le code x86 (nettoyé) que j’ai reçu de https://assembly.ynh.io/ :

 ssortingng_return_function: movl $.LC0, %eax ret 

.LC0 est simplement un emplacement contenant la chaîne. Donc, ce sont 2 instructions, y compris le retour de functin overhead / boilerplate. Assez efficace. 🙂

Vous pensez à ceci:

 char * bad_code(void) { char response[] = MY_STRING; return response; } 

Ce code est mauvais car il retourne un tableau local. Peu importe que le tableau en question soit initialisé à partir du littéral, ce n’est pas ce qui est retourné.

De plus, ne nommez pas votre fonction en commençant par str , tous ces noms sont réservés; le brouillon C11 dit:

Les noms de fonction commençant par str , mem ou wcs et une lettre minuscule peuvent être ajoutés aux déclarations dans l’en-tête .

Les littéraux de chaîne sont alloués dans la mémoire statique en lecture seule, généralement appelée .rodata (données en lecture seule). Ils persistent pendant toute la durée de votre programme, il est donc prudent de renvoyer un pointeur à un.

Si vous aviez toutefois copié le littéral chaîne dans une variable de stack temporaire, le code serait dangereux et invoque un comportement indéfini:

 char* ssortingng_return_function() { char myssortingng [] = "Ssortingng example"; return myssortingng; // BAD } 

Les littéraux de chaîne donnent un tableau de caractères avec une durée de stockage statique.

Par exemple, la norme C de 1999, section 6.4.5, paragraphe 5 commence par

Dans la phase de traduction 7, un octet ou un code de valeur zéro est ajouté à chaque séquence de caractères multi-octets résultant d’un littéral chaîne ou de littéraux. 65) contient la séquence.

La durée de stockage statique signifie que le tableau représentant le littéral de chaîne continue d’exister après le retour de la fonction ssortingng_return_function() .