我有功能转换数组中的列表:
void* list_to_array(SList* list)
{
int i;
int array_size = list_get_length(list);
void* array[array_size];
for (i = 0; i < array_size; i++)
{
array[i] = list_get_n_data(list,i);
}
return *array;
}
但是当我尝试测试时:
int* a = (int*)list_to_array(list);
printf("%d" (int)a);
没关系。我看到第一个元素。但是当我试图获得第二或第三个元素时:
int* a = (int*)list_to_array(list);
a++;
printf("%d" (int)a);
我看到第一个元素+ 4.如果我尝试获得第三个元素我看到第一个元素值+ 8等等......为什么?怎么了?
谢谢
答案 0 :(得分:6)
您正在返回指向堆栈内存位置的指针。一旦函数返回,该内存区域就不再有效。
此外,您不是实际返回指向数组的指针,而是返回数组中的第一个元素。以下代码将返回1,而不是指针数组。
int array[] {1, 2, 3, 4};
return *array
您可能只需对代码进行最少的更改即可使其正常工作。
void** array = (void **) malloc(sizeof(void *) * array_size);
...
return array;
确保在完成后释放内存用于array
的内存。
void **array = list_to_array(list);
// Use array
...
// Finished with array
free(array);
答案 1 :(得分:1)
当您将指针int* a
增加1时,它实际上会将其增加sizeof(int)
,这在大多数系统上至少为4
。
所以,如果
int* a = 0x40b8c438
然后
a + 1
= ((void*) a) + sizeof(int)
= 0x40b8c43c
和
a + 2
= ((void*) a) + sizeof(int) * 2
= 0x40b8c440
答案 2 :(得分:0)
这里有三个问题。第一个是微不足道的,你用return *array
返回数组的第一个元素,当你的意思是用return array
返回指向数组的第一个元素的指针。不要停在这里!第二个是你将指针递增1,而不是你指向的数据的大小。这会导致你得到错误的结果。第三个问题更严重:
您可以在此行上为阵列分配内存:
void* array[array_size];
此内存在堆栈上分配,从函数返回时不再分配此内存。稍后使用以下行引用此内存时:
int* a = (int*)list_to_array(list);
a指向堆栈中不再使用的区域。使用您的代码可以得到一些合理的结果,但是如果您在从函数返回后修改堆栈,则会指向新内存。例如,如果您使用以下代码:
int* a = (int*)list_to_array(list1);
int* b = (int*)list_to_array(list2);
printf("%d" (int)a);
你(可能)会看到b的第一个元素。这不保证 - 您可能还会遇到分段错误。分配给a
及其使用之间的其他代码也将覆盖您在printf语句中访问的内存的内容。
您需要使用与a相同的范围分配内存。
// Prototype
void* list_to_array(SList* list, void* dest_array);
// C99 (Or use malloc)
void* array[list_get_length(list)];
int* a = (int*)list_to_array(list, array);
other_functions();
// Works every time!
printf("%d" (int)a);
不太严重的问题是你没有按正确的数量增加指针。您需要使用sizeof()运算符。或者,您可以使用[]。
访问数组元素int* a = (int*)list_to_array(list, array);
printf("%d" a[1]); //Prints second element of a
a += sizeof(int) * 2;
printf("%d" (int)a); //Prints third element of a
答案 3 :(得分:0)
你需要小心指针,用这种方式声明:
int main()
{
int *array;
int i;
i = size(list);
array = list_to_array(list, i);
...
free(array);
}
int size(t_list *list)
{
int i;
i = 0;
while (list)
{
i++;
list = list->next;
}
return (i);
}
int *list_to_array(t_list *list, int size)
{
int *array;
int i;
t_list *temp;
i = 0;
if (list == NULL)
return (NULL);
array = (int*)malloc(sizeof(int) * size + 1);
temp = list;
while (temp)
{
array[i] = temp->data;
temp = temp->next;
i++;
}
return (array);
}