Carácter de retorno[]/cadena de una función [duplicate]

5 minutos de lectura

avatar de usuario
usuario1993177

Soy bastante nuevo en la codificación en C y actualmente estoy tratando de crear una función que devuelva una cadena de CA/matriz de caracteres y la asigne a una variable.

Hasta ahora, he observado que devolver un char * es la solución más común. Así que probé:

char* createStr() {
    char char1= 'm';
    char char2= 'y';
    char str[3];
    str[0] = char1;
    str[1] = char2;
    str[2] = '\0';
    char* cp = str;
    return cp;
}

Mi pregunta es ¿cómo uso esto devuelto? char* y asigne la matriz de caracteres a la que apunta, a un carácter[] ¿variable?

Lo he intentado (todo condujo a errores de ahogamiento de novatos):

  1. char* charP = createStr();
  2. char myStr[3] = &createStr();
  3. char* charP = *createStr();

  • mejor discusión por duplicado a pesar de que es más nuevo

    – Antti Haapala — Слава Україні

    7 de agosto de 2019 a las 5:44


avatar de usuario
ruben

Tenga en cuenta que no está asignando dinámicamente la variable, lo que significa que los datos dentro stren su función, se perderá al final de la función.

Deberías:

char * createStr() {

    char char1= 'm';
    char char2= 'y';

    char *str = malloc(3);
    str[0] = char1;
    str[1] = char2;
    str[2] = '\0';

    return str;

}

Luego, cuando llamas a la función, el tipo de la variable que recibirá los datos debe coincidir con el de la función devuelta. Entonces, deberías tener:

char *returned_str = createStr();

Vale la pena mencionar que el valor devuelto debe liberarse para evitar pérdidas de memoria.

char *returned_str = createStr();

//doSomething
...

free(returned_str);

  • sizeof(char) se garantiza que es 1 y no hay razón para encasillar el malloc regreso

    – Aniket Inge

    22 de enero de 2015 a las 4:37


  • @Aniket +1 Gracias por el comentario. Mis amigos me han dicho eso algunas veces, pero supongo que no entendí el problema en ese momento, y más tarde no volví a pensar en eso: D

    – Rubén

    22 de enero de 2015 a las 9:00

Si quieres devolver un char* de una función, asegúrese de malloc() eso. Las matrices de caracteres inicializados de la pila no tienen sentido al regresar, ya que acceder a ellos después de regresar de esa función es un comportamiento indefinido.

cambiarlo a

char* createStr() {
    char char1= 'm';
    char char2= 'y';
    char *str = malloc(3 * sizeof(char));
    if(str == NULL) return NULL;
    str[0] = char1;
    str[1] = char2;
    str[2] = '\0';
    return str;
}

  • Vale la pena mencionar que el valor devuelto debe liberarse para evitar pérdidas de memoria. char* astr = createStr(); doSomething(astr); free(astr);

    – Vasilis

    15/03/2016 a las 17:47

  • ¡Esto era lo que estaba buscando! Estaba un poco confundido al pensar que devolver un puntero desde la función puede causar pérdidas de memoria. Tu respuesta resolvió mi pregunta. Entonces, la memoria en poder de char *astr finalmente se libera. (En Java, por ejemplo, entiendo que esto no es un problema, porque el recolector de basura se encargaría)

    – hrushi

    23 de febrero de 2017 a las 19:46

avatar de usuario
ARSD

puede usar una matriz estática en su método, para evitar la pérdida de su matriz cuando finaliza su función:

char * createStr() 
{
    char char1= 'm';
    char char2= 'y';

    static char str[3];  
    str[0] = char1;
    str[1] = char2;
    str[2] = '\0';

    return str;
}

Editar: como mencionó Toby Speight, este enfoque no es seguro para subprocesos, y también recordar la función conduce a la sobrescritura de datos que no es deseada en algunas aplicaciones. Por lo tanto, debe guardar los datos en un búfer tan pronto como regrese de la función. (Sin embargo, debido a que no es un método seguro para subprocesos, las llamadas simultáneas aún podrían causar problemas en algunos casos, y para evitar esto, debe usar lock. capturarlo al ingresar a la función y liberarlo después de que se haya realizado la copia, prefiero no usar esto enfoque porque es desordenado y propenso a errores).

  • Probablemente valga la pena mencionar algunas de las desventajas (todas las llamadas comparten el mismo almacenamiento, por lo que las llamadas sobrescribirán los resultados anteriores y nada es seguro para subprocesos).

    –Toby Speight

    26 de febrero de 2020 a las 18:09

char* charP = createStr();

Sería correcto si su función fuera correcta. Desafortunadamente, está devolviendo un puntero a una variable local en la función, lo que significa que es un puntero a datos indefinidos tan pronto como la función regresa. Debe usar la asignación de almacenamiento dinámico como malloc para la cadena en su función para que el puntero que devuelva tenga algún significado. Entonces necesitas recordar liberarlo más tarde.

Incluir “string.h” facilita las cosas. Una forma más fácil de abordar su problema es:

#include <string.h>
    char* createStr(){
    static char str[20] = "my";
    return str;
}
int main(){
    char a[20];
    strcpy(a,createStr()); //this will copy the returned value of createStr() into a[]
    printf("%s",a);
    return 0;
}

  • ¿Por qué hacer una copia? char *a = createStr(); funcionaria igual.

    – melpomene

    11 de marzo de 2017 a las 11:56

  • Sí, también puede usar eso y eso ahorrará algo de memoria, es solo que pidió una forma de “asignar la matriz de caracteres a la que (la función) apunta, a un carácter[] variable”, así que le dije exactamente eso.

    – Adnán

    12 de marzo de 2017 a las 13:15

  • ¿Por qué hacer una copia? char *a = createStr(); funcionaria igual.

    – melpomene

    11 de marzo de 2017 a las 11:56

  • Sí, también puede usar eso y eso ahorrará algo de memoria, es solo que pidió una forma de “asignar la matriz de caracteres a la que (la función) apunta, a un carácter[] variable”, así que le dije exactamente eso.

    – Adnán

    12 de marzo de 2017 a las 13:15

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad