Solo por curiosidad, probé su código usando gcc en Linux, y es mucho más robusto de lo que esperaba (después de todo, escribir datos en un búfer de caracteres de longitud 0 es un comportamiento indefinido ... Lo haría esperar que se bloquee).
Aquí es mi modificación de su código:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p;
p = malloc(sizeof(char)*0);
printf("Hello Enter some without spaces :\n");
scanf("%s",p);
char *q;
q = malloc(sizeof(char)*0);
printf("Hello Enter more data without spaces :\n");
scanf("%s",q);
printf("The first string is '%s'\n",p);
printf("The second string is '%s'\n",q);
}
Mi primer pensamiento fue que puedas ser salvo por el hecho de que sólo está leyendo datos en una sola posición de memoria - si utiliza dos memorias intermedias, el segundo podría sobrescribir la primera ... así que se rompió el código en las secciones de entrada y salida:
Hello Enter some without spaces :
asdf
Hello Enter more data without spaces :
tutututu
The first string is 'asdf'
The second string is 'tutututu'
Si el primer tampón había sido sobrescrito, veríamos
The first string is 'tutututu'
The second string is 'tutututu'
Así que ese no es el caso. [Pero esto depende de la cantidad de datos que meter en cada búfer ... ver más abajo]
Entonces, pegué una increíble cantidad de datos en ambas variables:
perl -e 'print "c" x 5000000 . "\n" ' | xsel -i
(Esto puso de + 4 MB de 'c's en el buffer de copia). Pegué esto en la primera y en la segunda llamada scanf. El programa lo tomó sin una falla de segmentación.
Aunque no tuve un error de segmentación, el primer buffer se sobrescribió. No podría decirlo porque mucha información pasó volando por la pantalla.Aquí está un funcionamiento con menos datos:
$ ./foo
Hello Enter some without spaces :
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Hello Enter more data without spaces :
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
The first string is 'aaaaaaaaaaaa'
The second string is 'ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc'
Había un pequeño glifo después aaaaaaaaaaaa, que es como mi terminal representa un carácter Unicode que no se puede mostrar. Esto es típico de los datos sobreescritos: usted no sabe lo que va a sobrescribir sus datos ... es un comportamiento indefinido, por lo que es propenso a los demonios nasales.
La conclusión es que cuando escribe en la memoria que no ha asignado espacio para (explícitamente usando malloc o implícitamente con una matriz), está jugando con fuego. Tarde o temprano, sobrescribirá la memoria y se causará todo tipo de dolor.
La verdadera lección aquí es que C no hace límites verificando. Se felizmente le permite escribir en la memoria que no es de su propiedad. Puedes hacerlo todo el día. Su programa puede ejecutarse correctamente, y puede que no. Se puede bloquear, puede escribir datos dañados o puede funcionar hasta que escanee en un byte más de lo que usó durante la prueba. No le importa, así que tienes que hacerlo.
La caja de malloc(0)
es simplemente una caja especial de this question.
Fuera de tema ... Pero no es una buena práctica lanzar malloc return .. Ver [this] (http://stackoverflow.com/questions/605845/doi-i-cast-the-result-of-malloc) – Krishnabhadra
C no lo protege contra sobrepasar los búferes que le han asignado; debe tener cuidado de no hacer esto, pisoteará la memoria de otra persona. – Rup
posible duplicado de [¿Por qué Malloc (0) devuelve una dirección no nula en Windows?] (Http://stackoverflow.com/questions/9723030/why-does-malloc0-return-a-non-null-address- en la ventana) – Jay