Volcado del núcleo en el tipo de puntero (int to double) en C

Me encontré con este pedazo de código:

void incme(double *p) { *p += 1; } int i = 1; incme((double *)&i); /* WRONG */ 

Cuando bash ejecutarlo, obtengo un volcado de memoria. Qué está mal con este código. ¿No podemos escribir un puntero int a un tipo doble.

Gracias.

No estás lanzando un int a un double , estás lanzando un int * a un double * . Eso no es seguro si sizeof(double) y sizeof(int) no son lo mismo …

Incluso si combina los tamaños de almacenamiento, ¿cuál espera que sea la salida? Los tipos de punto flotante y los enteros tienden a no tener ningún tipo de representaciones compatibles.

(int) generalmente se alinea a 4 bytes en el hardware de 32 bits, mientras que (double) generalmente necesita estar alineado a 8 bytes. Si su i no está en una dirección alineada de 8 bytes, puede esperar SIGBUS ; también, si se asigna en la stack, es probable que el más grande (double) sobrescriba el marco de llamada, lo que lleva a un volcado del núcleo cuando incme() devuelve, si el anterior no lo mata.

Puede lanzar cualquier puntero de un tipo a otro, pero eso no lo hace correcto. En este caso, si sizeof (double)! = Sizeof (int) entonces la línea en “incme” probablemente escribirá en la memoria fuera de la asignada al entero “i”. Todas las apuestas están apagadas entonces.

Hay una diferencia entre la conversión de tipo y la reinterpretación de la memoria.

Su código convierte a la fuerza un puntero de tipo int * tipo double * . Eso se logra mediante el uso de un reparto explícito. Esta acción por sí sola no conduce necesariamente a ningún problema por sí misma. Por lo tanto, la suposición que hizo en el título de su pregunta es incorrecta. El “volcado de núcleo” que usted observa no tiene nada que ver con el mismo reparto.

Una vez que haya realizado la conversión, procederá a eliminar la referencia al puntero resultante y acceder (modificar) la memoria a la que apunta. Ahí es cuando el verdadero problema tiene lugar. El código realiza la reinterpretación de los datos: intenta acceder a un objeto de tipo int como un objeto de tipo double . Esto siempre es explícitamente ilegal en lenguaje C El locking que observa se debe específicamente a este bash de reinterpretación.

Por lo tanto, la respuesta corta a su pregunta es: ciertamente puede lanzar un puntero que apunta a un objeto int para double * tipo. Pero no puede desreferenciar el puntero double * resultante y acceder a la memoria como si tuviera un objeto double .

En la mayoría de las plataformas, el doble es de 8 bytes y el int 4, por lo tanto no, no puede convertir int * para duplicar * y usarlo

Una forma de hacerlo es:

 int i = 1; double d1 = (double)i; double *d = &d1; incme(d);