2012-03-13 11 views
12

Intenté probar la excepción bad_alloc pasando algunos argumentos negativos al new[]. Cuando paso pequeños números negativos, obtengo lo que esperaba: un bad_alloc. Sin embargo, al pasar -1, puedo ver que mi objeto se construye miles de veces (imprimo el contador estático en el constructor) y la aplicación finaliza con segfault.¿Por qué new [-1] genera segfault, mientras que new [-2] arroja bad_alloc?

new[] conversos entero de a size_t, por lo -1 es el máximo de size_t y -2 es el maximum - 1 y así sucesivamente.

Entonces, ¿por qué new[] arroja una excepción al recibir un gran número, pero trata de asignar al recibir el máximo de size_t? ¿Cuál es la diferencia entre 1111...1 y 1111...0 para new[]? :)

Gracias de antemano!

+2

Qué versión de compilador/compilador/OS/... – xanatos

+0

Esa vez perdí las respuestas porque StackOverflow no me envía ninguna notificación, y ahora no puedo reproducir el problema ... Lamento no haber generado volcados del núcleo y no lo investigué ... Ahora no puedo reproducir el problema - pasar -1 a 'nuevo' parece funcionar y arroja una excepción, mientras que pasar max int asigna muchos objetos pero no segfault. Estoy empezando a pensar que el problema estaba en otro lugar ... Doy un plus a Mystical por su intento. – flyjohny

Respuesta

17

Aquí es mi conjetura salvaje:

En muchas implementaciones, el asignador se coloque algunos meta-datos junto a la región asignada.
(Por ejemplo, el tamaño de la asignación.) Así que, en realidad, está asignando más de lo que pidió.

Supongamos size_t es de 32 bits. Compilado para 32 bits.


Al hacer:

int *array = new int[-1]; 

El -1 convierte -1 * 4 bytes = 4294967292 (después del desbordamiento). Pero si la implementación del asignador pone 4 bytes de metadatos al lado de la región asignada. El tamaño real se convierte en:

4294967292 + 4 bytes = 0 bytes (after overflow) 

Así 0 bytes se asignan realidad.

Cuando intenta acceder a la memoria, segfault ya que sale fuera de límites inmediatamente.


Ahora digamos que lo hace:

int *array = new int[-2]; 

El -2 se convierte en -2 * 4 bytes = 4294967288 (después del desbordamiento). Agregue 4 bytes de metadatos y obtenga 4294967288 + 4 = 4294967292.

Cuando el asignador solicita 4294967292 bytes del SO, se deniega. Entonces arroja bad_alloc.


Así que, básicamente, es posible que -1 y -2 hace la diferencia entre si es o no se desbordará después de que el asignador añade sus metadatos.

+0

Nunca he visto una implementación tan defectuosa en la naturaleza, – PlasmaHH

+0

+1. "Cuando intenta acceder a la memoria" - "usted" es 'new []' moviéndose para recorrer los elementos cree que asignó espacio, llamando a la colocación 'new' para invocar el constructor en cada ... –

+0

@ PlasmaHH Eso es lo que estoy pensando también. Estoy tratando de encontrar una fuente que me diga si algo de esto es un comportamiento indefinido. Pero aún no he encontrado nada. – Mysticial

Cuestiones relacionadas