Escribir al puntero fuera de límites después de que malloc () no haya causado el error

cuando pruebo el código a continuación, funciona bien. ¿Me estoy perdiendo de algo?

main() { int *p; p=malloc(sizeof(int)); printf("size of p=%d\n",sizeof(p)); p[500]=999999; printf("p[0]=%d",p[500]); return 0; } 

Lo probé con malloc (0 * sizeof (int)) o cualquier cosa, pero funciona muy bien. El progtwig solo falla cuando no uso malloc. Así que incluso si asigno 0 memoria para la matriz p, aún almacena valores correctamente. Entonces, ¿por qué me estoy molestando con Malloc?

Puede parecer que funciona bien, pero no es muy seguro en absoluto. Al escribir datos fuera del bloque de memoria asignado, sobrescribe algunos datos que no debería. Esta es una de las principales causas de segfeults y otros errores de memoria, y lo que está observando con lo que parece que funciona en este breve progtwig es lo que hace que sea tan difícil buscar la causa raíz.

Lea este artículo , en particular la parte sobre corrupción de la memoria, para comenzar a entender el problema.

Valgrind es una excelente herramienta para analizar errores de memoria como el que usted proporciona.

@David hizo un buen comentario. Compare los resultados de ejecutar su código para ejecutar el siguiente código . Tenga en cuenta los últimos resultados en un error de tiempo de ejecución (¡con prácticamente ninguna salida útil!) En ideone.com (haga clic en los enlaces), mientras que el primero tiene éxito como lo experimentó.

 main() { int *p; p=malloc(sizeof(int)); printf("size of p=%d\n",sizeof(p)); p[500]=999999; printf("p[0]=%d",p[500]); p[500000]=42; printf("p[0]=%d",p[500000]); return 0; } 

Si no asigna memoria, p tiene basura, por lo que escribir en ella probablemente fallará. Una vez que haya realizado una llamada malloc válida, p apunta a una ubicación de memoria válida y puede escribir en ella. Está sobrescribiendo la memoria en la que no debe escribir, pero nadie va a sostener su mano y contarle al respecto. Si ejecuta su progtwig y un depurador de memoria como valgrind, se lo dirá. Bienvenido a C.

Al final de su memoria, se ha escrito Undefined Behavior ™, lo que significa que podría pasar cualquier cosa, incluido que su progtwig funcione como si lo que acaba de hacer fuera perfectamente legal. El motivo por el que su progtwig se ejecuta como si hubiera hecho malloc(501*sizeof(int)) es completamente específico de la implementación, y puede ser específico para cualquier cosa, incluida la fase de la luna.

Esto se debe a que a P se le asignaría alguna dirección sin importar el tamaño que use con malloc (). Aunque con un tamaño cero estaría haciendo referencia a la memoria no válida ya que no se ha asignado la memoria, pero puede estar dentro de una ubicación que no causaría la falla del progtwig, aunque el comportamiento no estará definido.

Ahora bien, si no usa malloc (), estaría apuntando a una ubicación de almacenamiento de basura y tratar de acceder a ella es probable que cause un locking del progtwig.

Lo intenté con malloc (0 * sizeof (int))

De acuerdo con C99, si el tamaño pasado a malloc es 0, un tiempo de ejecución de C puede devolver un puntero NULL o la asignación se comporta como si la solicitud fuera para asignación distinta de cero, excepto que el puntero devuelto no debe desreferenciarse. Por lo tanto, está definida su implementación (por ejemplo, algunas implementaciones devuelven un búfer de longitud cero) y en su caso no obtiene un puntero NULL, pero está utilizando un puntero que no debería estar utilizando. Si lo prueba en un tiempo de ejecución diferente, podría recuperar un puntero NULL.

Cuando llamas a malloc (), una pequeña porción de memoria está tallada en una página más grande para ti.

  malloc(sizeof(int)); 

En realidad, no asigna 4 bytes en una máquina de 32 bits (el asignador lo rellena hasta un tamaño mínimo) + tamaño de los metadatos de montón utilizados para rastrear el fragmento a lo largo de su vida útil (los trozos se colocan en contenedores según su tamaño y marcados en uso) o gratis por el asignador). hxxp: //en.wikipedia.org/wiki/Malloc o más específicamente hxxp: //en.wikipedia.org/wiki/Malloc#dlmalloc_and_its_derivatives si está probando esto en Linux.

Así que escribir más allá de los límites de tu porción no necesariamente significa que vas a colapsar. En p + 5000 no está escribiendo fuera de los límites de la página asignada para ese fragmento inicial, por lo que técnicamente está escribiendo en una dirección asignada válida. Bienvenido a la corrupción de la memoria. http://www.google.com/search?sourceid=chrome&ie=UTF-8&q=heap+overflows

Nuestra herramienta CheckPointer puede detectar este error. Sabe que la asignación de p fue a un trozo de 4 bytes, y así se realiza la asignación, está fuera del área para la que se asignó p. Le dirá que la asignación p [500] es incorrecta.