¿Su ejemplo de "actualización" está completo? No creo que compile: requiere un valor de retorno pero nunca devuelve nada. Nunca harás nada que sea un camino completo, pero tal vez sea deliberado, tal vez tu punto sea solo decir que cuando haces malloc, otras cosas se rompen.
Sin ver al que llama, es imposible decir definitivamente lo que está sucediendo aquí. Mi suposición es que las rutas es un bloque asignado dinámicamente que se liberó antes de llamar a esta función. Dependiendo de la implementación del compilador, un bloque libre todavía podría parecer que contiene datos válidos hasta que un malloc futuro tome el control del espacio.
Actualización: para realmente responder a la pregunta
manejo de cadenas es un problema bien conocido en C. Si se crea una matriz de tamaño fijo para contener la cadena, usted tiene que preocuparse de una larga cadena de desbordamiento el espacio asignado. Esto significa verificar constantemente los tamaños de cadena en las copias, utilizando strncpy y strncat en lugar de strcpy simple y strcat, o técnicas similares.Puede omitir esto y simplemente decir: "Bueno, nadie podría tener un nombre de más de 60 caracteres" o algo así, pero siempre existe el peligro de que alguien lo haga. Incluso en algo que debería tener un tamaño conocido, como un número de seguridad social o un ISBN, alguien podría cometer un error al ingresar y pulsar una tecla dos veces, o un usuario malintencionado podría ingresar algo deliberadamente. Etc. Por supuesto, esto es principalmente un problema en la entrada de datos o lectura de archivos. Una vez que tienes una cadena en un campo de un tamaño conocido, entonces para cualquier copia u otra manipulación, conoces el tamaño.
La alternativa es utilizar almacenamientos intermedios asignados dinámicamente donde puede hacerlos tan grandes como sea necesario. Esto suena como una buena solución cuando lo escuchas por primera vez, pero en la práctica es un dolor gigante en C, porque asignar los búferes y liberarlos cuando ya no los necesitas es un montón de problemas. Otro cartel aquí dice que la función que asigna un buffer debe ser la misma que lo libera. Una buena regla general, generalmente estoy de acuerdo, pero ... ¿Qué pasa si una subrutina quiere devolver una cadena? Entonces asigna el buffer, lo devuelve, y ... ¿cómo puede liberarlo? No puede porque todo el asunto es que quiere devolverlo a la persona que llama. La persona que llama no puede asignar el búfer porque no conoce el tamaño. Además, cosas aparentemente simples como:
if (strcmp(getMeSomeString(),stringIWantToCompareItTo)==0) etc
son imposibles. Si la función getMeSomeString asigna la cadena, seguro, puede devolverla para que hagamos la comparación, pero ahora hemos perdido el control y nunca podemos liberarlo. Se termina por tener que escribir código difíciles como
char* someString=getMeSomeString();
int f=strcmp(someString,stringIWantToCompareItTo);
free(someString);
if (f==0)
etc
Así bien, funciona, pero la legibilidad de disminuir, simplemente.
En la práctica, he encontrado que cuando se puede esperar razonablemente que las cadenas sean de un tamaño cognoscible, asigno búferes de longitud fija. Si una entrada es más grande que el búfer, ya sea truncarlo o dar un mensaje de error, dependiendo del contexto. Solo recurro a los buffers asignados dinámicamente cuando el tamaño es potencialmente grande e impredecible.
Creo que, más o menos, estás haciendo algo que invoca un comportamiento indefinido. Antes de echarle la culpa al compilador o al sistema operativo, sugiero que compartas algún código de ejemplo con nosotros, para que podamos decirte si tu código original que funcionó en OS X es realmente válido. –
Eso solo se ve ... mal al menos. ¿Asignas a la matriz (???) ... a la que quieres aplicar strcpy? Usted tiene un returntr pero devuelve localstr (en la pila, ¡vaya!), Etc. De todos modos, bienvenido al divertido mundo de C. La propiedad de los objetos (sí, C también los tiene) debe estar claramente definida. Por ejemplo, ¿qué ocurre si el código anterior se invoca como myfunction ("¡Hola mundo!") - de todos modos, define los contratos. Un enfoque es hacer que el CALLER sea responsable de pasar un objeto válido capaz de tomar n caracteres (si se requieren más, la llamada fallará, etc.) –
No entiendo qué significa "C realmente estricta". Estoy de acuerdo con Michael en que el "comportamiento realmente extraño" que estás viendo es simplemente un comportamiento indefinido dado el código anterior. No hay una forma especial de pasar una "cuerda" en C, funciona igual que cualquier otra matriz. ¿Qué es exactamente lo que estás teniendo un problema? –