我正在尝试键入一个函数,需要2链表。其中一个包含要打印的值,第二个包含要打印的链表值的位置。它给了我一个错误,我把它作为代码中的注释。
结构
typedef int Item;
typedef struct node_struct * link;
typedef struct list_struct * list;
struct node_struct {
Item item;
link next;
};
struct list_struct {
link first;
int length;
};
功能:
list sublist(list A, list pos_list) {
link tempOne;
link tempTwo;
link node = malloc(sizeof *node);
tempOne = pos_list->first;
tempTwo = A->first;
int counter;
while(tempOne->next != NULL)
{
counter = 0;
while(counter < tempOne->item && tempOne->next != NULL)
{
tempTwo = tempTwo->next;
counter = counter+1;
}
node->item = tempTwo->item; //EXC_BAD_ACCESS code:1
node = node->next;
tempTwo = A->first;
tempOne = tempOne->next;
counter = 0;
}
return node;
代码中有一堆不好的做法,这使得理解(从而调试和维护)这样的代码对你和我们来说都非常困难。
- 当不打算隐藏指针后面的实际数据时,您正在创建指针typdef
- 您正在创建位置链表和数据链表,使用相同的数据类型。在你的情况下,我理解两者都是int,但不要使用误导性的
typedef int Item
,只需坚持使用int
-
tempOne
和tempTwo
可能是最糟糕的命名选项,在这种情况下,不仅调用具有非直观名称的变量,如temp
,而且还将第一个参数称为Two
,第二个参数称为One
-作为反直觉的,因为它可以得到 - 我可以看到你使用2种不同的结构
node_struct
(坦率地说,我会称之为node
)和list_struct
(参见node_struct
注释)的情况,但在这个例子中,你不需要list_struct
,它只会给代码增加更多的混乱。 - 你应该在一个单独的函数中做"查找"工作(内部
for loop
),这样你就可以很容易地处理错误,而不会混淆内部循环和外部循环
在此基础上,您没有指定pos_list
实际上是否包含相对位置(从前一个位置的位置)或绝对位置(如数组索引)。我将假定它是绝对位置。
在你做node = node->next;
之后,你需要再次做malloc
。或者更确切地说,在node->item = tempTwo->item;
行使用它之前将其malloc,并将malloc
从循环中删除
我手边没有c编译器,所以不能测试它。但我看不出有其他问题
编辑
我注意到sublist的返回值总是最后一个节点,而不是链表中的第一个节点——这显然也是一个问题。
下面是我将如何编写这段代码。请记住,这不是经过调试和测试的代码,而仅仅是想法的表达(如果您愿意,可以是初稿)typedef struct Node_ Node;
struct Node_ {
int Item;
Node* Next;
};
Node* GetNodeAt(Node *dataList, int indx) {
for (int i = 0; i < indx && dataList != NULL; ++i)
dataList = dataList->Next;
return dataList;
}
Node* SubList(Node *dataList, Node *posList) {
Node* origDataList = dataList;
Node *currentRetNode = malloc(sizeof(Node));
Node *prevRetNode = NULL, *returnList = currentRetNode;
while (posList->Next != NULL) {
// Find the node in dataList
Node *node = GetNodeAt(dataList, posList->Item);
// create/manage the linked list to be returned
prevRetNode = currentRetNode;
currentRetNode->Next = malloc(sizeof(Node));
currentRetNode->Item = node->Item;
currentRetNode = currentRetNode->Next;
posList = posList->Next; // move to the next index
}
free(currentRetNode);
if (prevRetNode == NULL)
returnList = NULL;
else
prevRetNode->Next = NULL;
return returnList;
}