69 votes

Quelle est la différence entre un char * et un char [] de retour d’une fonction ?

Pourquoi la première fonction renvoie la chaîne « Hello, World », mais la seconde fonction ne renvoie rien. J’ai pensé que la valeur de retour de deux des fonctions serait indéfinie car ils retournent des données qui sont hors de portée.

71voto

El Profesor Points 10915

la deuxième fonction ne retourne rien

L' string tableau dans la seconde fonction:

char string[] = "Hello, World!";

a automatique de la durée de stockage. Il n'existe pas après le contrôle de flux est retourné par la fonction.

Alors qu' string dans la première fonction:

char* string = "Hello, World!";

points d'une chaîne littérale, qui a statique de la durée de stockage. Cela implique que, la chaîne existe toujours après le retour de la fonction. Ce que vous êtes de retour de la fonction est un pointeur vers cette chaîne littérale.

27voto

Joachim Pileborg Points 121221

La première chose que vous devez savoir à propos des chaînes est qu'un littéral de chaîne est vraiment un tableau de lire uniquement les caractères avec une durée de vie de la totalité du programme. Cela signifie qu'ils ne seront jamais hors de portée, ils vont toujours exister tout au long de l'exécution du programme.

Ce que la première fonction (function1) ne retourne un pointeur vers le premier élément d'un tableau.

La deuxième fonction (function2), les choses sont un peu différentes. Ici, la variable string est une variable locale dans la fonction. En tant que tel, il sera hors de portée et cessent d'exister une fois que la fonction retourne. Cette fonction permet de retourner un pointeur vers le premier élément de ce tableau, mais le pointeur va immédiatement devenir invalide car elle pointe vers quelque chose qui n'existe plus. Un déréférencement (ce qui se passe quand vous la passez printf) conduira à un comportement indéfini.

7voto

Paul Smith Points 15

Une chose très importante à retenir lors du codage en C ou autre pile en fonction des langues, c'est que lorsqu'une fonction retourne, elle et tous ses locaux de stockage) est parti. Cela signifie que si vous voulez que quelqu'un d'autre pour être en mesure de voir les résultats de vos méthodes de travail, vous devez le mettre quelque part, qui va encore exister après votre méthode a cessé d', et pour faire cela signifie que vous avez besoin pour obtenir une bonne compréhension de où C stocke les choses et comment.

Vous le savez probablement déjà comment un tableau opère dans C. C'est une adresse de mémoire qui est incrémenté par la taille de l'objet et vous savez probablement que C ne pas faire la vérification des limites donc, si vous voulez accéder à la 11ème élément d'une dizaine d'élément de tableau, personne ne va vous arrêter, et tant que vous n'essayez pas d'écrire quoi que ce soit, pas de dégâts. Ce que vous ne pouvez pas savoir, c'est que C étend cette idée de la façon dont il utilise des fonctions et de variables. Une fonction est une zone de la mémoire sur une pile est chargée à la demande et le stockage de ses variables sont juste des décalages à partir de cet emplacement. Votre fonction retourné un pointeur vers une variable locale, plus précisément, l'adresse d'un emplacement sur la pile qui détient le " H " de "Hello World\n\0", mais lorsque vous avez appelé une autre fonction (par la méthode d'impression) que la mémoire a été réutilisé par la méthode d'impression de faire ce dont il avait besoin. Vous pouvez le voir assez facilement (NE PAS le FAIRE DANS la PRODUCTION de CODE!!!)

char* foo2 = function2(); // Prints nothing
ch = foo2[0];  // Do not do this in live code!
printf("%s\n", foo2);  // stack used by foo2 now used by print()
printf("ch is %c\n", ch);  // will have the value 'H'!

5voto

haccks Points 33022

Je pensais que la valeur de retour de deux fonctions seraient pas défini depuis, ils sont de retour de données qui est hors de portée.

Pas de. Ce n'est pas le cas.

Dans la fonction function1 retourner un pointeur vers une chaîne littérale. De retour pointeur vers une chaîne de caractères littérale est bien parce que les littéraux de chaîne ont statique de la durée de stockage. Mais ce n'est pas vrai avec automatique variable locale.

Dans la fonction function2 le tableau string est automatique variable locale et de la déclaration

return string; 

retourne un pointeur vers une automatique variable locale. Une fois le retour de la fonction, la variable string n'existera plus. Un déréférencement du pointeur retourné va provoquer un comportement indéfini.

1voto

Dmitry Grigoryev Points 1495

"Hello, World!" est un littéral de chaîne, qui a une durée de stockage statique, de sorte que le problème est ailleurs. Votre première fonction renvoie la valeur de string, ce qui est bien. La deuxième fonction, cependant renvoie l' adresse d'une variable locale (string est le même que &string[0]), ce qui entraîne un comportement indéfini. Votre deuxième printf déclaration d'impression de rien, ou de "Hello, World!", ou quelque chose d'autre entièrement. Sur ma machine, le programme devient juste une erreur de segmentation.

Toujours prendre un coup d'oeil à vos messages du compilateur sorties. Pour votre exemple, gcc donne:

file.c:12:12: warning: function returns address of local variable [-Wreturn-local-addr]
    return string; 
           ^

qui est à peu près de soi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X