使用gcc上的指针将值存储在手动位置时出错

问题描述 投票:-3回答:3
#include<stdio.h>

int main(void){

    int a[3] = {1,2,3};
    int *p;

    p = &a+2;

    // here p and &a+2 will going to be same...having some particular address on memory

    *p = 56;

    // m writing 56 on *(p) or *(&a+2)...

    printf("%d %d\n",*p,*(&a+2));

    return 0;
}

o / p显示我是什么!! *p = 56*(&a+2) =与&a+2相同......

对于p = &a+1,它给了我一堆粉碎......

*(*(&a+2))给我想要的结果56 ...

任何人都可以向我解释这背后的确切原因是什么?

c pointers
3个回答
1
投票
p = &a+2;

在功能上等同于

p = &(a[6]);

因为在&a上加两个sizeof(a)*2&a,而sizeof(a)*2等于sizeof(a[0])*3*2。取消引用生成的指针会引发未定义的行为,因为它超出了数组的末尾。


#include <stdio.h>

int main(void) {
    int a[3] = {1,2,3};
    int *p = &a+2;
    printf("a    @ %p\n", (void*)a);
    printf("a    @ %p\n", (void*)&a);
    printf("a[0] @ %p\n", (void*)&(a[0]));
    printf("a[2] @ %p\n", (void*)&(a[2]));
    printf("p    = %p\n", (void*)p);
    printf("a[6] @ %p\n", (void*)&(a[6]));
    return 0;
}

$ gcc -Wall -Wextra -pedantic --std=c99 a.c -o a && a
a.c: In function ‘main’:
a.c:5:14: warning: initialization from incompatible pointer type [enabled by default]
     int *p = &a+2;
              ^
a    @ 0x3878b9c3030
a    @ 0x3878b9c3030
a[0] @ 0x3878b9c3030
a[2] @ 0x3878b9c3038
p    = 0x3878b9c3048
a[6] @ 0x3878b9c3048

0
投票

你的意思是p=a+2;,而不是p=&a+2;。后者形成一个指向数组a(使用&a)的指针,然后尝试形成一个指向不存在的其他数组的指针(如果它存在,它将是多维数组中的一行)。很少使用指向数组的指针,这有助于人们混淆数组和指向它们decay的指针。


0
投票

任何人都可以向我解释这背后的确切原因是什么?

原因是您正在调用未定义的行为,因此您的编译器以及您的程序可以执行它想要的任何操作。这几乎就是“未定义行为”的定义:标准没有说明正确的事情是什么,所以程序可以做任何事情。

仅仅因为*(*(&a+2))给出了正确的答案并不意味着&a+2是有效的代码。在很多情况下,未定义的行为可能导致工作程序,但不能保证这样的程序将继续工作,甚至在您进行进一步更改时继续编译。

正如几个人已经指出的那样,未定义的行为来自p = &a+2,它将未初始化的地址分配给不兼容的指针。

© www.soinside.com 2019 - 2024. All rights reserved.