Renvoi de la chaîne depuis la fonction C

Je n’ai pas utilisé C depuis plus de 3 ans, je suis assez rouillé sur beaucoup de choses.

Je sais que cela peut sembler stupide mais je ne peux pas renvoyer une chaîne d’une fonction pour le moment. Veuillez supposer que: je ne peux pas utiliser ssortingng.h pour cela.

Voici mon code:

 #include  char * getStr(int length) { char word[length]; for (int i = 0; i < length; i++) { word[i] = getch(); } word[i] = '\0'; return word; } int main() { char wordd[10]; initscr(); *wordd = getStr(10); printw("The string is:\n"); printw("%s\n",*wordd); getch(); endwin(); return 0; } 

Je peux capturer la chaîne (avec ma fonction getStr ) mais je ne parviens pas à l’afficher correctement (j’ai des ordures).

L’aide est appréciée.

Soit allouez la chaîne sur la stack côté appelant et transmettez-la à votre fonction:

 void getStr(char *wordd, int length) { ... } int main(void) { char wordd[10 + 1]; getStr(wordd, sizeof(wordd) - 1); ... } 

Ou rendez la chaîne statique dans getStr :

 char *getStr(void) { static char wordd[10 + 1]; ... return wordd; } 

Ou allouez la chaîne sur le tas:

 char *getStr(int length) { char *wordd = malloc(length + 1); ... return wordd; } 
 char word[length]; char *rtnPtr = word; ... return rtnPtr; 

Ce n’est pas bien. Vous retournez un pointeur sur une variable automatique (étendue), qui sera détruite au retour de la fonction. Le pointeur restra orienté vers une variable détruite, ce qui produira presque certainement des résultats “étranges” (comportement indéfini).

Vous devriez atsortingbuer la chaîne avec malloc (par exemple, char *rtnPtr = malloc(length) ), puis la free plus tard dans main .

Vous allouez votre chaîne sur la stack, puis vous lui renvoyez un pointeur. Lorsque votre fonction revient, toute allocation de stack devient non valide. le pointeur pointe maintenant vers une région de la stack susceptible d’être écrasée lors du prochain appel d’une fonction.

Afin de faire ce que vous essayez de faire, vous devez effectuer l’une des opérations suivantes:

  1. Allouez de la mémoire sur le tas en utilisant malloc ou similaire, puis renvoyez ce pointeur. L’appelant devra alors appeler free fois la mémoire mémorisée.
  2. Allouez la chaîne sur la stack dans la fonction appelante (celle qui utilisera la chaîne) et transmettez un pointeur à la fonction dans laquelle placer la chaîne. Pendant tout l’appel de la fonction appelante, les données de sa stack sont valides. ce n’est que lorsque vous retournez que la stack allouée devient utilisée par autre chose.

Votre pointeur pointe vers la variable locale de la fonction. Ainsi, dès que vous revenez de la fonction, la mémoire est désallouée. Vous devez affecter de la mémoire sur le tas pour pouvoir l’utiliser dans d’autres fonctions.

Au lieu de cela char *rtnPtr = word;

faites ceci char *rtnPtr = malloc(length);

Pour qu’il soit disponible dans la fonction principale. Après utilisation, libérez de la mémoire.

word est sur la stack et sort de la scope dès que getStr() retour. Vous invoquez un comportement indéfini.

Plus facile encore: retourne un pointeur sur une chaîne qui a été malloc’d avec strdup .

 #include  char * getStr(int length) { char word[length]; for (int i = 0; i < length; i++) { word[i] = getch(); } word[i] = '\0'; return strdup(&word[0]); } int main() { char wordd[10]; initscr(); *wordd = getStr(10); printw("The string is:\n"); printw("%s\n",*wordd); getch(); endwin(); return 0; } 

Je suis tombé sur ce fil en travaillant sur ma compréhension de Cython. Mon extension à la question initiale pourrait être utile à d’autres personnes travaillant à l’interface C / Cython. Il s’agit donc de l’extension de la question initiale: comment renvoyer une chaîne d’une fonction C en la mettant à la disposition de Cython et donc de Python?

Pour ceux qui ne le connaissent pas, Cython vous permet de taper de manière statique le code Python dont vous avez besoin pour accélérer. Le processus consiste donc à écrire Python :), à le trouver un peu lent quelque part, à le profiler, à supprimer une ou deux fonctions et à les cythoniser. Sensationnel. Vitesse proche de C (comstack en C) Fixe. Yay. L’autre utilisation est d’importer des fonctions C ou des bibliothèques dans Python comme cela est fait ici.

Ceci imprimera une chaîne et renverra la même chaîne ou une autre chaîne à Python. Il y a 3 fichiers, le fichier c_hello.c, le fichier cython sayhello.pyx et le fichier d’installation cython sayhello.pyx. Lorsqu’ils sont compilés à l’aide de python setup.py build_ext --inplace ils génèrent un fichier de bibliothèque partagée pouvant être importé dans python ou ipython et la fonction sayhello.hello est exécutée.

c_hello.c

 #include  char *c_hello() { char *mystr = "Hello World!\n"; return mystr; // return "this ssortingng"; // alterative } 

sayhello.pyx

 cdef extern from "c_hello.c": cdef char* c_hello() def hello(): return c_hello() 

setup.py

 from setuptools import setup from setuptools.extension import Extension from Cython.Distutils import build_ext from Cython.Build import cythonize ext_modules = cythonize([Extension("sayhello", ["sayhello.pyx"])]) setup( name = 'Hello world app', cmdclass = {'build_ext': build_ext}, ext_modules = ext_modules )