从void双指针数组输出void指针

问题描述 投票:0回答:2

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

#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

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

c arrays stdout void-pointers
2个回答
1
投票

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

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

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()内容。


0
投票

希望我能为您提供帮助。

  1. malloc保留空间(您可能已经知道)并返回void *,而不是void **。我将使用:

    对其进行初始化。
    const int capacity = 4;
    int* array = (int*)malloc(capacity*sizeof(int)); 
    

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

  1. [printf()中有一个')'过多;
© www.soinside.com 2019 - 2024. All rights reserved.