将列表转换为数组

时间:2010-08-18 15:15:11

标签: c arrays list

我有功能转换数组中的列表:

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等等......为什么?怎么了?

谢谢

4 个答案:

答案 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);
}