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)。
有人知道我在做什么错吗?
似乎您正在将堆栈上的变量地址存储到数组中。仅有一个堆栈变量(list1
),因此每次其地址都相同。或可能有所不同,但实际上实际上只有一个有效的list1
对象。
您也不应在超出范围后使用堆栈地址。因此,一旦离开create
函数,存储在数组中的地址就会无效。
如果要创建由十个结构组成的数组,则可以执行List array[10];
。如果要动态分配每个结构,可以使用List *array[10];
,然后将使用new
或malloc
分配的指针分配给数组(或其他有效指针)。
C编程语言的漏洞之一是,您可以从函数返回指向局部变量的指针。这就是函数create中发生的事情。下次调用该函数时,变量list1的值未定义。如果您不能使用动态内存分配,为什么不简单地声明一个列表数组而不是列表指针呢?
函数create
的两次调用将同一局部变量list1
的地址存储在数组array
中,并将此地址返回给调用方。
List* create() {
List list1;
//...
array[size] = &list1;
//..
return array[size++];
//...
}
所以主plist1
和plist2
中的两个指针都具有相同的无效值,因为局部变量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;
}
在这种情况下,当不再需要已分配的内存时,您应该忘记释放它。