我是C语言的新手,但我一直将插入函数卡在链表中。当我尝试打印列表时。结果不是我期望的。我知道它与指针有关,但是我无法理解。我在这里做什么错了?
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
typedef struct CELL_NODE CellNode;
struct CELL_NODE {
int row;
int column;
CellNode *next;
};
struct LinkedList {
CellNode *head;
};
typedef struct LinkedList LinkedList;
void printList(LinkedList *myList) {
CellNode *curr = (*myList).head;
if (curr != NULL) {
printf("(%d,%d)", (*curr).row, (*curr).column);
if ((*curr).next != NULL) {
curr = (*curr).next;
printf(" - (%d,%d)", (*curr).row, (*curr).column);
}
} else {
printf("The list is empty");
}
printf("\n");
}
void insert(LinkedList *myList, CellNode *node) {
CellNode *ref = (*myList).head;
if (ref == NULL) {
(*myList).head = node;
} else {
while ((*ref).next != NULL) {
ref = (*ref).next;
}
(*ref).next = node;
}
}
int main(int argc, char *argv[]) {
LinkedList myList = { NULL };
for (int k = 0; k < 2; k++) {
CellNode myNode = { 1, k, NULL };
insert(&myList, &myNode);
printList(&myList);
printf("\n");
}
return 1;
}
我得到的结果是:
(1,0) (1,1) - (1,1)
我期望:
(1,0) (1,0) - (1,1)
答案 0 :(得分:1)
您应该首先将(*x).y
的每个实例更改为x->y
,以使代码更具可读性。
然后,看下面的代码:
int main(int argc, char *argv[])
{
LinkedList myList = {NULL};
for(int k = 0 ; k<2 ; k++) {
CellNode myNode = {1,k,NULL};
insert(&myList,&myNode);
printList(&myList);
printf("\n");
}
return 1;
}
您将myNode
创建为for
循环内的局部变量。这意味着循环的每次迭代都会获得myNode
的新实例,从而破坏前一个实例。因此,您已经通过指针将myNode
连接到链接列表,然后下次通过for
循环将其销毁。
如果要让一段代码隐藏指向某个对象的指针,则必须确保该对象保持有效,直到不再有可能取消引用那些指针为止。
您需要做出决定-链表包含指向的对象将拥有?那一辈子什么时候结束?当它们结束时,什么将摧毁它们?
您尚未执行此操作。因此,您的对象的生命周期结束得太早。
答案 1 :(得分:1)
使用
CellNode myNode = {1,k,NULL};
insert(&myList,&myNode);
您正在传递一个指向局部变量的指针。该变量的生命期与循环的相应迭代一样长,即在第二次迭代中,第一次迭代的对象不在范围内。因此,您将访问一个生命周期已由您存储在列表中的指针结束的对象。这会产生不确定的行为。
使用动态生成的对象代替(并且不要忘记稍后释放它们):
CellNode *myNode = malloc(sizeof(CellNode));
myNode->row = ...
答案 2 :(得分:0)
您反复从立即超出范围的局部变量中将节点插入到链表中。该行为是不确定的,您的程序可能会以许多无法预测的方式失败。
您应该这样修改代码:
insert
函数以将元素数据作为参数并使用malloc()
分配一个新节点。printList()
打印完整列表,而不仅仅是前几个单元格。(*pointer).member
表示法更改为等效但更惯用的pointer->member
表示法。0
返回main
,以成功进行操作。这是修改后的版本:
#include <stdio.h>
#include <stdlib.h>
typedef struct CellNode CellNode;
struct CellNode {
int row;
int column;
CellNode *next;
};
typedef struct LinkedList LinkedList;
struct LinkedList {
CellNode *head;
};
void printList(LinkedList *myList) {
CellNode *curr = myList->head;
if (curr != NULL) {
printf("(%d,%d)", curr->row, curr->column);
while (curr->next != NULL) {
curr = curr->next;
printf(" - (%d,%d)", curr->row, curr->column);
}
} else {
printf("The list is empty");
}
printf("\n");
}
CellNode *insert(LinkedList *myList, int row, int column) {
CellNode *node = malloc(sizeof(*node));
CellNode *ref = myList->head;
if (node != NULL) {
if (ref == NULL) {
myList->head = node;
} else {
while (ref->next != NULL) {
ref = ref->next;
}
ref->next = node;
}
}
return node; // return node pointer to allow the caller to detect out of memory error
}
int main(int argc, char *argv[]) {
LinkedList myList = { NULL };
CellNode *node;
for (int k = 0; k < 2; k++) {
insert(&myList, 1, k);
printList(&myList);
printf("\n");
}
// free the nodes
while ((node = myList->head) != NULL) {
myList->head = node->next;
free(node);
}
return 0;
}