rip retorno resaca electrica current corriente c string return local-variables

retorno - Devolver cadena de la función C



corriente de retorno electrica (7)

No he usado C en más de 3 años, estoy bastante oxidado en muchas cosas.

Sé que esto puede parecer estúpido, pero no puedo devolver una cadena de una función en este momento. Suponga que: no puedo usar string.h para esto.

Aquí está mi código:

#include <ncurses.h> 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; }

Puedo capturar la cadena (con mi función getStr ) pero no puedo hacer que se muestre correctamente (obtengo basura).

La ayuda es apreciada.


Asigne la cadena en la pila en el lado de la persona que llama y páselo a su función:

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

O haga que la cadena sea estática en getStr :

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

O asigne la cadena en el montón:

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


Encontré este hilo mientras trabajaba en mi comprensión de Cython. Mi extensión a la pregunta original podría ser útil para otras personas que trabajan en la interfaz de C / Cython. Entonces esta es la extensión de la pregunta original: ¿cómo devuelvo una cadena de una función C, dejándola disponible para Cython y, por lo tanto, para Python?

Para aquellos que no están familiarizados con él, Cython le permite escribir estáticamente el código Python que necesita para acelerar. Entonces, el proceso es, disfruta escribiendo Python :), encuentra que es un poco lento en alguna parte, perfílalo, deja una función o dos y ciptizalas. Guau. Cerca de la velocidad C (se compila a C) Fijo. Hurra. El otro uso es importar funciones C o bibliotecas en Python como se hace aquí.

Esto imprimirá una cadena y devolverá la misma u otra cadena a Python. Hay 3 archivos, el archivo c c_hello.c, el archivo cython sayhello.pyx y el archivo de configuración de cython sayhello.pyx. Cuando se compilan con python setup.py build_ext --inplace , generan un archivo de biblioteca compartida que se puede importar a python o ipython y se ejecuta la función sayhello.hello.

c_hello.c

#include <stdio.h> char *c_hello() { char *mystr = "Hello World!/n"; return mystr; // return "this string"; // 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 )


Está asignando su cadena en la pila y luego le devuelve un puntero. Cuando su función regresa, cualquier asignación de pila se vuelve inválida; el puntero ahora apunta a una región en la pila que probablemente se sobrescribirá la próxima vez que se llame a una función.

Para hacer lo que estás tratando de hacer, debes hacer uno de los siguientes:

  1. Asigne memoria en el montón utilizando malloc o similar, luego devuelva ese puntero. La persona que llama deberá llamar free cargo cuando termine con la memoria.
  2. Asigne la cadena en la pila en la función de llamada (la que usará la cadena) y pase un puntero a la función para colocar la cadena. Durante toda la llamada a la función de llamada, los datos en su pila son válidos; es solo una vez que devuelve esa pila, el espacio asignado se usa por otra cosa.

Más fácil aún: devuelva un puntero a una cadena que ha sido mal colocada con strdup .

#include <ncurses.h> 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; }


Su puntero apunta a la variable local de la función. Tan pronto como regrese de la función, la memoria se desasigna. Debe asignar memoria en el montón para usarla en otras funciones.

En cambio char *rtnPtr = word;

hacer esto char *rtnPtr = malloc(length);

Para que esté disponible en la función principal. Después de que se usa, libera la memoria.


word está en la pila y queda fuera de alcance en cuanto getStr() regresa. Estás invocando un comportamiento indefinido.


char word[length]; char *rtnPtr = word; ... return rtnPtr;

Esto no está bien. Está devolviendo un puntero a una variable automática (de ámbito), que se destruirá cuando regrese la función. El puntero se dejará apuntando a una variable destruida, que casi con seguridad producirá resultados "extraños" (comportamiento indefinido).

Debería asignar la cadena con malloc (por ejemplo, char *rtnPtr = malloc(length) ), y luego free más tarde en main .