所以我想用 C 语言编写一个函数,将通用数组转换为单个链表。
我编写的代码:
typedef struct Node {
struct Node* next;
void *value;
} Node;
void insert(Node** root, void* value) {
Node* new_node = (Node *) malloc(sizeof(Node));
Node* ptr;
new_node->value = value;
new_node->next = NULL;
if (*root == NULL)
*root = new_node;
else {
ptr = *root;
while (ptr->next != NULL)
ptr = ptr->next;
ptr->next = new_node;
}
}
Node* arr2list(void* array, size_t length) {
Node *root = NULL;
for(int i = 0; i < length; i++) {
insert(&root,&array[i]);
}
return root;
}
我为它编写了一个小测试:
int main() {
int arr[] = { 1, 2, 3, 4, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
Node* root = arr2list(arr, n);
while (root != NULL)
{
printf("%d,",*(int*) root->value);
root = root->next;
}
return 0;
}
但我得到垃圾值:-13308,-2145276560,-2145276560,-2145276560,-2145276560,
。
我似乎找不到导致这些结果的错误。
可能是什么问题?
最佳答案
您的程序包含 &array[i]
,其中 array
在第 28 行具有类型 void*
。
这不是标准 C。GCC 接受它并将指针算术视为 char* 算术(可以说是一个坏主意,特别是因为它在像这样的示例中造成了困惑)。
由于您的函数arr2list
通过一些未对齐的指针消耗数组,因此结果显然是任意值(包含第一个数组元素的一些字节和第二个数组元素的一些字节) ,例如)。
我很高兴地说,函数 arr2list
必须简单地将一个元素的长度作为参数,但仅这一微小的变化本身不足以使事情正常进行。您的链表类型将指针存储为数据,因此该函数还需要为每个元素分配一个 block ,并在 Node
内存储指向该元素的指针。
如果您满足于让列表指向数组的元素,那么忘记上面的段落,您几乎有了一个可行的解决方案,只需让 arr2list
接受一个额外的参数 size_t elt_size
并使用 (char*)array + elt_size*i
而不是 &array[i]
。
关于c - C 中的通用列表包含垃圾值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57579141/