2017-10-11 22 views
-5

Je mets le code directement.Le double pointeur pointe vers la variable int pour écraser la mémoire

#include <stdio.h> 
struct A 
{ 
    int a; 
    int b; 
}; 
int main() 
{ 
    struct A test; 
    double *p = (double *)&(test.a); 
    *p = 5; 

    printf("variable a: %d\n", &test.a); 
    printf("variable b: %d\n", &test.b); 
    return 0; 
} 

Je lance ce code dans centos7, le compilateur est gcc4.8.5 .And mon ordinateur utilise peu fin pour stocker.

Comme vous le voyez, la mémoire de la variable b sera écrasé, je me attendais a est 0x0000 0005 et b est 0x0000 0000.

Mais la réponse est:

variable a: 0 
variable b: 1075052544 

Pourquoi variables a est 0x 0000 0000 et b est 0x4014 0000?

+5

Ce comportement est indéfini. En outre, le 'double' 5 correspond à l'entier' 0x4014000000000000' de 64 bits, donc vous pouvez probablement comprendre ce qui se passe. Astuce: 'double' peut être plus grand que' int'. – unwind

+3

Vous obtenez un résultat inattendu parce que vous avez menti à votre compilateur, et il a trouvé un moyen de revenir à vous. Vous avez dit au compilateur que '& (test.a)' est une adresse d'un 'double', mais c'est une adresse d'un nombre entier. – dasblinkenlight

+0

Vous pouvez manipuler les paramètres d'optimisation et demander à votre compilateur de compiler du code où le résultat est quelque chose d'autre *. –

Répondre

4

Le comportement de votre code est undefined.

Vous ne pouvez pas déréférencer p une fois que vous l'avez défini à l'adresse de quelque chose qui n'est pas un type double.

Pour voir ce que votre compilateur a fait avec cette entrée, vérifiez l'assemblage généré.

+0

Dans mon ordinateur, 'int' occupe 4 octets,' double' occupe 8 octets, j'utilise un double pointeur sur int et affectation, il devrait remplacer la valeur de la variable b, donc je pense que b devrait être 5, a devrait être 0. Et '1075052544' est une valeur fixe qui ne change pas avec chaque exécution ou changement d'optimisation. – UKeeySDis

+1

Vous pouvez penser à ce que vous voulez penser. Ce n'est évidemment pas ce qui se passe. Le fait demeure que le comportement est indéfini. – Bathsheba

+0

Le double 5 correspond à l'entier 64 bits '0x4014000000000000'. Donc, je reçois' b' est '0x4014 0000', la valeur de la variable b est l'autre moitié des 4 octets. – UKeeySDis

1

Le comportement de votre code n'est pas défini.

compilateur Clang générer un message d'avertissement:

source_file.c:13:20: warning: format specifies type 'int' but the argument has type 'int *' [-Wformat] 
    printf("%d\n", &test.a); 
      ~~  ^~~~~~~ 
source_file.c:14:20: warning: format specifies type 'int' but the argument has type 'int *' [-Wformat] 
    printf("%d\n", &test.b); 
      ~~  ^~~~~~~