首页 > 解决方案 > 指针数组如何存储在内存中以及如何正确取消引用它们?

问题描述

int main(void) {

    int* b[3] = {1, 2, 3};      // b is an array of pointers to integer

    printf("%d", b);            // b = address of array of pointers
    printf("\n%d", *b);         // *b should be address of the place where 1 is stored ....right?
    printf("\n%d", *(b+1));     // similarly *(b+1) should be address of place where 2 is stored
    printf("\n%d", *(b+2));     // and so on... But they print 1,2 and 3

    printf("\n%d", b[0]);       // prints 1 . No problem!


    printf("%d", *(*(b+1)+2));  // Also why does this give segmentation fault?


    //PLUS I GET THIS WARNING : array_of_pointers2.c:5:13: warning: initialization makes pointer from integer without a cast [-Wint-conversion]

    //PLEASE EXPLAIN !! I think I have misunderstood something.


    return 0;
}

下面我附上了我认为如何存储它们的草图。如果我错了,请用更好的草图纠正我。 在此处输入图像描述

标签: carrayspointers

解决方案


您的代码有很多问题,主要是因为int *b[3]没有适当的初始化程序。{ 1, 2, 3 }可以用于 的数组int,而不是 的数组int *,因为编译器正确诊断:

array_of_pointers2.c:5:13: warning: initialization makes pointer from integer without a cast [-Wint-conversion]

为了与古代代码兼容,编译器仅发出警告,但此类警告表示必须纠正的错误。我强烈建议你编译你的代码,-Wall -Werror让编译器产生错误,而不是仅仅对这些问题发出警告。

访问地址12或者3很可能有未定义的行为,这表现为系统上的分段错误。

要初始化指针数组,您可以指定int变量的地址。

这是一个更正的版本:

#include <stdio.h>

int main(void) {
    int x = 1, y = 2, z = 3;
    int *b[3] = { &x, &y, &z };           // b is an array of pointers to integer

    printf("        b: %p\n", (void*)(b));         // b = address of array of pointers
    printf("       *b: %p\n", (void*)(*b));        // *b is the address of variable x that has a value of 1
    printf("   *(b+1): %p\n", (void*)(*(b+1)));    // similarly *(b+1) is the address of y where 2 is stored
    printf("   *(b+2): %p\n", (void*)(*(b+2)));    // and so on...

    printf("    *b[0]: %d\n", *b[0]);     // prints 1. No problem!
    printf("*(*(b+1)): %d\n", *(*(b+1))); // prints 2
    // accessing *(*(b+1)+2) would have undefined behavior because b[1] is 
    // not the address of an array of at least 3 ints.
    printf("  b[2][0]: %d\n", b[2][0]);   // prints 3

    return 0;
}

请注意,指针无法打印,%d因为它具有未定义的行为,因为指针可能以不同的方式从整数传递到printf. 格式是%p并且指针应该被转换(void*)为完全可移植性。


推荐阅读