泛型列表包含C中的垃圾值
所以我想用C编写一个函数,将一个通用数组转换成一个链表 我编写的代码: 但我得到垃圾值:泛型列表包含C中的垃圾值,c,arrays,pointers,linked-list,C,Arrays,Pointers,Linked List,所以我想用C编写一个函数,将一个通用数组转换成一个链表 我编写的代码: 但我得到垃圾值:-13308,-2145276560,-2145276560,-2145276560,-2145276560,-2145276560, 我似乎找不到导致这些结果的错误 有什么问题吗?您的程序包含&array[i]其中array在第28行有类型void* 这不是标准的C语言。GCC接受它,并将指针算法视为char*算法(可以说是一个坏主意,特别是因为它在这样的示例中加剧了混淆) 由于函数arr2list通过一些
-13308,-2145276560,-2145276560,-2145276560,-2145276560,-2145276560,
我似乎找不到导致这些结果的错误
有什么问题吗?您的程序包含
&array[i]
其中array
在第28行有类型void*
这不是标准的C语言。GCC接受它,并将指针算法视为char*算法(可以说是一个坏主意,特别是因为它在这样的示例中加剧了混淆)
由于函数arr2list
通过一些未对齐的指针使用数组,因此结果显然是任意值(例如,包含第一个数组元素的一些字节和第二个数组元素的一些字节)
我很高兴地说,函数arr2list
必须简单地将一个元素的长度作为参数,但仅此小小的更改本身并不足以使事情正常进行。链表类型将指针存储为数据,因此函数还需要为每个元素分配一个块,并在节点中存储指向此元素的指针
如果您满足于让列表指向数组的元素,那么忘记上面的段落,您几乎有了一个有效的解决方案,只需让arr2list
使用一个额外的参数size\t elt\u size
,并使用(char*)array+elt\u size*i
而不是&array[i]
,它说:“需要算术或指针类型的'void'类型的错误操作数”。问题的第一个版本似乎是正确的。为什么要更改它?@user3386109有人建议更改它(虽然它是正确的,但后来他删除了他的注释)Johnny,这是一个列表,但不是数组。是的,他错了。问题是arr2list
void*array
的声明应该是int*array
。我使用C99
。那么,我如何替换&
?@vesiivoid*
算法在任何C标准中都没有定义。不是在C89中,不是在C99中,也不是在C中11.如果您使用的是GCC,请尝试使用类似c99编译器的东西。问题不在于您使用的是&
,而在于您的函数arr2list
试图在不知道指针指向的元素大小的情况下偏移指针。您所说的算术是什么意思下面的链接有一个void*
的例子:我所说的“void*
算术”在较长的术语中是“使用void*
指针的指针算术”。它不是C。GCC使它像“char*
算术”或“使用char*
指针的指针算术”一样工作,这不是您想要的。如果出现编译错误,您会得到更好的服务,而标准C编译器会提供编译错误。@vesii换句话说,您的错误与Johnny Mopp在评论中指出的问题中的错误相似。
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;
}