为什么使用printf打印变量的地址会更改地址

时间:2015-11-28 08:10:09

标签: c arrays

代码1

#include <stdio.h>
int main()
{
    int n[] = {0};
    int i = 1;
    n[0] = i; //making sure the variable is used
    n[-1] = 20; //i's offset when &i is printed
    printf("%d\n", &i);
    printf("%d\n", i);
    return 0;
}

输出1

2686744
20

代码2

#include <stdio.h>
int main()
{
    int n[] = {0};
    int i = 1;
    n[0] = i; //making sure the variable is used
    n[1] = 20; //i's offset when &i isn't printed
    printf("%d\n", i);
    return 0;
}

输出2

20

如果我在打印时使用1作为偏移,而在不打印时使用-1,则不会发生覆盖。我已经尝试打印其他地址和值,但没有更多的事情发生。

我认为它与i变量的使用无关,因为我试图为编译器添加一些代码来认为它已被使用。

还尝试在没有优化的情况下显式编译(-O0),而不对结果进行更改。

2 个答案:

答案 0 :(得分:7)

使用类似int n[] = {0};的定义,数组中只有一个元素,即n[0]是唯一有效的访问权限。

在您的第一个代码中,

 n[-1] = 20;

是无效的内存访问。

在你的第二个代码中,

n[1] = 20;

也是访问超出限制的内存。这两种情况都会调用undefined behavior

另外,要打印地址,您需要使用%p格式说明符并将参数转换为(void *)

答案 1 :(得分:0)

有些事情要小心...... 在第一个代码中,打印它“i”及其方向,但有一个小错误   n [-1] = 20

这些代码行对于打印并不重要,它会脱离数组..

第二个代码......

它也有一个小错误n [1] = 20;