Problemas para devolver una cadena desde la función

Estoy teniendo problemas con los principios básicos de las cadenas en C. Tengo una función:

char *editStr(char *str) { char new[strlen(str)]; ... do some editing ... return new; } 

¿Cómo devolvería la matriz de caracteres llamada “nuevo”. Como entiendo, el valor de retorno de la función es un char *, lo que significa que está pidiendo un puntero al primer carácter de una cadena. En este momento, creo que el problema es que estoy devolviendo un carácter de matrices. Intenté devolver un puntero al primer carácter en “nuevo”, pero eso tampoco parece funcionar. Intenté “return * new [0]”. Mi conocimiento de la cadena es malo.

Hay varios problemas aquí, pero el problema de matriz / puntero con return new; no es uno de ellos

Primero, quieres:

 char new[strlen(str) + 1]; 

Para que tengas suficiente espacio para el terminador nulo.

Tu new está asignado en la stack, por lo que devolverlo solo causará dolor y confusión; querrás

 char *new = malloc(strlen(str) + 1); 

en lugar de eso, para que la memoria siga siendo válida cuando la función regrese.

En cuanto a su pregunta real, una matriz en C es la dirección del primer elemento, por lo que su return new; está bien (sujeto al problema de stack versus stack mencionado anteriormente). C las matrices se descomponen a los punteros en un abrir y cerrar de ojos para que no tenga que preocuparse por devolver una matriz cuando se declara que la función devuelve un puntero.

Estás devolviendo un puntero a algo que has creado en la stack. No puedes hacer eso.

Necesita memoria malloc() del montón y devolverla (y luego free() más tarde

 char *editStr(char *str) { char *newArray = malloc(strlen(str) +1); ... do some editing ... return newArray; } 

EDITAR : Porque olvidé agregar 1 para el terminador de cadena. También puede usar strdup() si desea comenzar con una copia de la cadena original.

Esto es lo que veo:

  1. La palabra “nuevo” es una palabra clave de C ++. No lo uses para nombrar una variable
  2. Si desea editar la cadena, edite str directamente.
  3. Si necesita hacer una copia, use malloc (strlen (str)) para asignar la memoria adicional.

Este artículo describe el problema que está teniendo y cómo lidiar con él.

La mejor manera de devolver un puntero a una matriz en C es así:

 char *getArr() { char *retbuf = malloc(25); if(retbuf == NULL) return NULL; return retbuf; } 

new variable está asignada a la stack y no puede devolver la referencia de una variable de la stack.

 char *editStr(char *str) { char new[strlen(str)]; ... do some editing ... return new; } // At this point, Unwinding of stack begins. // new is on stack and the memory allocated to it is deallocated. // So, the returned reference is only pointing to garbage. 

En su lugar, debes usar malloc y free una vez que esté hecho.

 char *new = malloc( strlen(str) + 1 ) ; // +1 for the the termination character 

Cuando crea una matriz C normal, solo existirá dentro del ámbito en el que la creó (en este caso, la función editStr() ) y se destruirá tan pronto como regrese de esa función. Por lo tanto, si estuviera devolviendo el puntero de la matriz, sería inútil, y si intentara usarlo, su progtwig probablemente se bloquearía.

En su lugar, debe asignar arreglos dinámicamente usando malloc() . Es bastante fácil de usar:

  char *a = (char*) malloc(sizeof(char) * 5); 

Esto crearía una matriz de 5 caracteres que podría usar, e incluso pasar entre funciones. Sin embargo, no se destruyen automáticamente cuando quedan fuera del scope, por lo que debe destruirlos manualmente usando free(a) cuando haya terminado con los punteros, o de lo contrario terminará con una pérdida de memoria.

Ver también:

  • malloc en Wikipedia
  • malloc en la referencia de C ++
  • malloc manual de malloc

Si está trabajando en un entorno de un solo hilo y el valor se usa inmediatamente, puede hacer que el búfer interno estético y estará disponible incluso después de salir de la función:

  char *editStr(char *str) { static char new[strlen(str)]; ... do some editing ... return new; } 

También puede usar el estilo antiguo de sprintf simple: pase un puntero a un búfer para la función y llénelo por dentro.

  int editStr(char *str, char *new, int new_size) { ... do some editing ... return 0; //can return error }