【问题标题】:Assigning address of pointer to pointer-to-pointer将指针的地址分配给指针到指针
【发布时间】:2019-07-15 09:04:05
【问题描述】:

我正在尝试使用指针制作一段简单的 c 代码,但内存被意外覆盖。

我想创建一个指向整数的指针数组,然后创建一个指向整数的指针并将其地址分配给数组。

因此,数组将指向一个指向整数的指针。我在一个名为 add_value_to_array() 的函数中完成了这项工作。

这是我的代码:

void add_value_to_array(int *** array, int * value) {
    *array = &value;
}
int main() {

    int ** arr = { 0 };
    int value = 5;
    int * value_ptr =  &value;

    add_value_to_array(&arr, value_ptr);
    //arr = &value_ptr;
    printf("looool\n");
    printf("looool\n");
    printf("looool\n");
    printf("looool\n");
    printf("%p\n", arr[0]);

}

我想要的是:

arr -> value_ptr -> 5
(arr = &value_ptr
*array = value_ptr
value_ptr = &value
*value_ptr = 5
**arr = 5)

但是,这是我在调用 add_value_to_array() 之后所拥有的,但是当我调用 printfs() 时,内存被覆盖,我在 arr 变量中得到了垃圾值。

更奇怪的是,如果我直接使用arr = &value_ptr 而不是调用add_value_to_array,事情会按预期进行,并且内存不会被printfs() 覆盖。

因此,如果我使用函数或在函数之外执行操作,似乎内存分配不同。

我看到这种行为是怎么回事?

【问题讨论】:

  • 数组在c 中不是动态的(您不能在c 中向“内置”数组添加/删除新项目)。你也可以检查一下:stackoverflow.com/questions/3536153/c-dynamically-growing-array
  • *array = &value; 是失败的秘诀。 value 是该函数的自动变量。函数返回后它就不存在了,因此它的地址进入了以太。出于任何原因保存该地址几乎是在运行程序之前出现问题的迹象。

标签: c pointers pointer-to-pointer


【解决方案1】:

以下假设:您希望创建一个长度为 1 的数组(以后可能更长),其中包含指向 int 的指针。并且您希望数组中的单个指针指向名为“value”的局部变量。

然后:

int* arr[] = { 0 }; // or { NULL }, if you prefer
//       ^  creates an array; either you specify size explicitly or it will be deduced
//          from initializer, as in this case

如果将数组传递给函数,数组会自动衰减为指向第一个元素的指针。所以:

add_value_to_array(arr, &value);
//                 ^ decays to pointer
//                        ^ here you still need a pointer; you can create it directly, though

剩下的小问题:arr 衰减到指针的类型是 int**。您的函数中需要相同的类型:

void add_value_to_array(int** array, int* value)
//                          ^ one asterisk less
{
    *array
//  ^ this one is NOW correct: array points to the first element of arr
//    dereferencing gives you exactly this element, i. e. the pointer

        = /* & */value;
//           ^ must be dropped: you already have a pointer and you assign it to
//             another one, which is fine.
}

请注意,指针只是内存中某处变量的地址。有点简化:

int n = 10;
int* p0 = &n;
int* p1 = &n; // p1 and p0 point both to the same variable n
int* p2 = p0; // now again p2 points to n
*p0 = 12;     // change the value pointed to
printf("%d\n", *p2); // will print 12, as both pointers point to the same address.

函数参数在这方面没有区别,它们只是普通变量。如果指针是数据值或指针本身,它就不起作用:

int n = 10;
int m = 12;
int* p = &n;
int** p1 = &p; // pointer to pointer to int
int** p2 = p1; // both p1 and p2 point to p
*p1 = &m;      // re-assign the POINTER
printf("%d\n", **p2); // again prints 12:
                      // p1 and p2 both point to p which was reset to m, though...

【讨论】:

    【解决方案2】:

    谢谢大家的回答,这帮助我找到了错误: 我必须按地址而不是按值传递我的 value_ptr。
    这是我更正的代码:

    void add_value_to_array(int *** array, int ** value_ptr) {
        *array = value_ptr;
    }
    int main() {
    
        int ** arr = { 0 };
        int value = 5;
        int * value_ptr =  &value;
    
        add_value_to_array(&arr, &value_ptr);
        //arr = &value_ptr;
        printf("looool\n");
        printf("looool\n");
        printf("looool\n");
        printf("looool\n");
        printf("%p\n", arr[0]);
    
    }
    

    感谢大家的帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-10
      • 1970-01-01
      • 2018-05-16
      • 2011-08-23
      • 1970-01-01
      • 2021-01-18
      • 2014-08-23
      相关资源
      最近更新 更多