[数组中的C指针分配

问题描述 投票:1回答:3
typedef struct {
    int head
} List;

List* array[10];
int size = 0;

List* create() {

    if(size < 10){

        List list1;
        list1.head = size;
        array[size] = &list1;
        printf("%d \n", array[size]->head); //value is stored perfectly here
        printf("%p \n", array[size]);       //same value printed everytime (e.g 0x7ffeee1139f0 )
        return array[size++];
    }
    return NULL;
}

int main() {
    List* plist1 = List_create();
    printf("%p \n", plist1);//same value 0x7ffeee1139f0

    List* plist2 = List_create();
    printf("%p \n", plist2);//same value 0x7ffeee1139f0
}

对于上面的以下代码,当我尝试遍历数组并在每个索引处打印值时,该值应该是我创建的每个列表结构的地址,因此应该是唯一的。

但是我在数组的每个索引处获得了相同的地址。我不知道为什么。

同样,当我遍历数组并打印array [index]-> head时,我得到了一些垃圾值(例如-477361872)。

有人知道我在做什么错吗?

c pointers memory-address
3个回答
1
投票

似乎您正在将堆栈上的变量地址存储到数组中。仅有一个堆栈变量(list1),因此每次其地址都相同。或可能有所不同,但实际上实际上只有一个有效的list1对象。

您也不应在超出范围后使用堆栈地址。因此,一旦离开create函数,存储在数组中的地址就会无效。

如果要创建由十个结构组成的数组,则可以执行List array[10];。如果要动态分配每个结构,可以使用List *array[10];,然后将使用newmalloc分配的指针分配给数组(或其他有效指针)。


0
投票

C编程语言的漏洞之一是,您可以从函数返回指向局部变量的指针。这就是函数create中发生的事情。下次调用该函数时,变量list1的值未定义。如果您不能使用动态内存分配,为什么不简单地声明一个列表数组而不是列表指针呢?


0
投票

函数create的两次调用将同一局部变量list1的地址存储在数组array中,并将此地址返回给调用方。

List* create() {
    List list1;
    //...
    array[size] = &list1;
    //..
    return array[size++];
    //...
}

所以主plist1plist2中的两个指针都具有相同的无效值,因为局部变量list1在函数create之外不存在。

您应该为List类型的对象动态分配内存。

例如

List* create() {

    if(size < 10){

        List *list1 = malloc( sizeof( List ) );

        if ( list1 != NULL )
        {
            list1->head = size;
            array[size] = list1;
            printf("%d \n", array[size]->head);
            printf("%p \n", ( void * )array[size]);
            return array[size++];
        }
    }

    return NULL;
}

在这种情况下,当不再需要已分配的内存时,您应该忘记释放它。

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