【问题标题】:Output void pointer from void double pointer array从 void 双指针数组输出 void 指针
【发布时间】:2020-04-01 04:41:55
【问题描述】:

我需要实现一个包含 void 指针的可变长度数据数组。我遇到了一个问题,当尝试从这个数组打印时,我总是输出最后一个元素。 这是我的问题和尝试实现的抽象说明:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int capacity = 4; // for example

    void **array = malloc(capacity*sizeof(void*));
    // assign values to array elements
    for(int i = 0; i < capacity; i++) {
        array[i] = malloc(sizeof(void*)); // not sure if it necessary
        int a = i*i;
        array[i] = &a;
        printf("index: %d, element: %d\n", i, *(int*)array[i]); // for demonstration
    }
    printf("\n");
    /*
    * after that I try to print all the elements of the array sequentially
    */
    for(int i = 0; i < capacity; i++) {
        printf("index: %d, element: %d\n", i, *(int*)array[i]));
    }

    // I know that I do not free my memory, but that’s not the point
    return 0;
}

我得到的输出如下:

index: 0, element: 0
index: 1, element: 1
index: 2, element: 4
index: 3, element: 9

index: 0, element: 9
index: 1, element: 9
index: 2, element: 9
index: 3, element: 9

(编辑问题:在 cmets 中,他们向我指出错误在于将变量放入质量中,因为我没有考虑 for 循环中变量的生命周期和指针原理) 如何在不引入一堆额外变量的情况下正确填充类似的数组?还是我选择的方法完全不正确? 如果有任何帮助,我将不胜感激

【问题讨论】:

  • array[i] = &amp;a; 存储指向循环本地变量的指针 - 循环结束后,您的数组中有很多悬空指针
  • 请阅读更多关于变量的范围和lifetime。
  • 还想一想array[i] = ... 后跟array[i] = ... 的真正作用。
  • 好。谢谢。这意味着我误解了程序显示的本质,我的错误不在输出中,而是将元素放入数组中。我怎样才能做到正确?将项目保存到另一个数组然后指向它?

标签: c arrays stdout void-pointers


【解决方案1】:

您会看到“最后一个元素”,因为a 在每次迭代中都停留在堆栈的相同位置,因此&amp;a 将那个特定的单个地址存储到所有元素中。然后地址包含写入那里的最后一个值 - 直到当其他任何东西覆盖它时它变成完全垃圾。

您需要不同的地址,因此您需要在循环内为每个数字分配内存。哪种情况已经发生,只需为void* 分配内存,而您需要int,然后覆盖它,(正如 cmets 已经指出的那样)您根本不应该这样做:

array[i] = malloc(sizeof(int));
*(int*)array[i] = i*i;
printf("index: %d, element: %d\n", i, *(int*)array[i]); // for demonstration

然后它起作用了:https://ideone.com/dF4KY8(一个额外的)已从末尾删除)
当然,正如您自己的评论所暗示的那样,您需要 free() 东西。

【讨论】:

    【解决方案2】:

    希望能帮到你。

    1. malloc 保留空间(您可能已经知道)并返回 void*,而不是 void**。我会初始化它:

      const int capacity = 4;
      int* array = (int*)malloc(capacity*sizeof(int)); 
      

    我不会将数组初始化为 void** 因为您计划在其中存储许多整数 它和一个 int 数组只不过是一个 int*。 如果您已经在开始时初始化了数组,则不必 再次调用malloc。 'malloc',返回分配内存的地址 适合您,但您已经知道要将数据存储在哪里。如果你有一个 void**,它是一个多维数组。剩下的一件事:失败时 malloc 返回一个空指针,检查数组是否为空,不会伤害您。 :)

    1. printf() 中的 ')' 过多;

    【讨论】:

      猜你喜欢
      • 2013-12-18
      • 2014-05-30
      • 2021-07-22
      • 2016-05-23
      • 2011-08-10
      • 1970-01-01
      • 2016-11-23
      • 2013-11-14
      • 1970-01-01
      相关资源
      最近更新 更多