【发布时间】:2021-12-27 22:47:17
【问题描述】:
[ 哇 - 有人给了我和我的问题的负面观点] [你至少可以评论一下你为什么不喜欢我的问题]
我被困住了。 我记得在 C++ 中做过类似的事情,但由于某种原因,我无法让它在普通 C 中工作。
我正在尝试交换单链表中的 2 个节点。
起始列表填充为[9,8,7,5,3,2],我正在尝试对其进行冒泡排序,一次2个节点到[2,3,5,7,8,9]的最终列表
第一次迭代(交换)使用头部查找。列表完美返回 [8,9,7,5,3,2]
...但是在第二次迭代中,我松开了 7 并得到了 WTF 的 [8,9,5,3,2],我尝试稍微更改代码但我失去了希望。
真的有人能找出我做错了什么吗?请不要使用双指针...如果只能使用双指针...为什么以及如何?因为我不知道什么是双指针?
到目前为止,这是我的程序:
/*
___ENTER TITLE HERE___
Author : Patrick Miron
Date : Oct 20, 2021
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct listNode
{
int data;
struct listNode *next;
} listNode;
typedef struct list
{
struct listNode *head;
struct listNode *tail;
} list;
int isEmpty( const list *l)
{
return (l == NULL);
}
void printList(list *ptrToList, char *title)
{
int counter = 0; //Counter to count the listItem printed so we can add a carriage return at each 5th element.
printf("%s\n", title);
listNode *ptrToCurrentItem = ptrToList->head;
while (ptrToCurrentItem != NULL)
{
counter++;
printf("%d", ptrToCurrentItem->data);
if (counter % 5 != 0)
{
printf(" : ");
}
else
{
printf("\n");
}
ptrToCurrentItem = ptrToCurrentItem->next;
}
}
list *createListWithHeadData(int data)
{
list *ptrList = malloc((sizeof(ptrList)));
listNode *ptrNewNode = malloc(sizeof(listNode));
ptrNewNode->data = data;
ptrList->head = ptrNewNode;
ptrList->tail = ptrNewNode;
return ptrList;
}
void addToFrontList(list *ptrList, listNode *ptrListNode)
{
listNode *tempPtr = ptrList->head;
ptrList->head = ptrListNode;
ptrListNode->next = tempPtr;
}
list *arrayToList(int data[], int size)
{
list *ptrToNewList = createListWithHeadData(data[0]);
for (int i = 1; i < size; i++)
{
listNode *ptrToNewListNode = malloc(sizeof(listNode));
ptrToNewListNode->data = data[i];
addToFrontList(ptrToNewList, ptrToNewListNode);
}
return ptrToNewList;
}
int count(listNode *ptrToHead)
{
if (ptrToHead == NULL)
{
return 0;
}
else
{
return (1 + count(ptrToHead->next));
}
}
void concat(listNode *head1, listNode *head2)
{
assert(head1 != NULL);
if (head1->next == NULL)
{
head1->next = head2;
}
else
{
concat(head1->next, head2);
}
}
void insert(
listNode *p1, // first element
listNode *p2, // second element
listNode *q) // new element to insert between first and second element
{
assert(p1->next == p2);
p1->next = q;
q->next = p2;
}
void delete(listNode *listNode)
{
assert(listNode != NULL);
listNode = NULL;
}
void deleteList(list *list)
{
if (list->head != NULL)
{
list->head = list->head->next;
deleteList(list);
}
}
void swapListNodeWithNext(listNode *ptrToListNode1)
{
//Swap items
listNode *ptrTempNode1 = ptrToListNode1->next;
listNode *ptrTempNode2 = ptrToListNode1->next->next;
//Set the next node from temp1 (ptrToListNode->next->next) to itself
//Could be written as ptrToListNode->next->next = ptrToListNode
ptrTempNode1->next = ptrToListNode1;
ptrToListNode1->next = ptrTempNode2;
ptrToListNode1 = ptrTempNode1;
ptrTempNode1 = NULL;
ptrTempNode2 = NULL;
}
void sortList(list *ptrToListToSort)
{
if (ptrToListToSort->head == NULL)
{
return;
}
listNode *ptrToCurrentItem = ptrToListToSort->head;
listNode *ptrToLastUnsortedItem = ptrToListToSort->tail;
while (ptrToLastUnsortedItem != ptrToListToSort->head)
{
ptrToCurrentItem = ptrToListToSort->head;
while(ptrToCurrentItem->next != NULL)
{
if (ptrToCurrentItem->data > ptrToCurrentItem->next->data)
{
listNode *ptrToHead = ptrToListToSort->head;
if (ptrToCurrentItem == ptrToListToSort->head)
{
ptrToHead = ptrToCurrentItem->next;
}
//Swap items
swapListNodeWithNext(ptrToCurrentItem);
ptrToListToSort->head = ptrToHead;
}
else
{
ptrToCurrentItem = ptrToCurrentItem->next;
}
}
ptrToLastUnsortedItem = ptrToCurrentItem;
}
}
int main(void)
{
printf("\n");
list listOfInt;
int data[6] = { 2, 3, 5, 7, 8, 9 };
list *ptrToNewList = arrayToList(data, 6);
printList(ptrToNewList, "Array to Element List");
sortList(ptrToNewList);
printList(ptrToNewList, "Sorted List");
printf("\n");
printf("...End of line...\n");
printf("\n");
return 0;
}
【问题讨论】:
-
那是很多代码。如果您的编译器支持它,我建议您使用 AddressSanitizer。如果您使用
g++或clang++,请尝试使用-g -fsanitize=address,undefined进行编译。它会在您运行程序时向您报告like this,以便您查看程序何时出现异常。 -
list *ptrList = malloc((sizeof(ptrList)));显然是错误的;ptrList是一个指向list结构的指针,但您只分配了足够的内存来存储一个指向列表结构的 指针。理想情况下,该行应为list *ptrList = malloc(sizeof *ptrList);。并保持一致;下一行按 type 的大小分配,而这一行(不正确)按 var 的大小分配。 -
谢谢@WhozCraig,我纠正了我的错字。但这不是我的问题。
-
谢谢@TedLyngmo,我从您发送给我的链接的地址清理程序中得到的只是:==1==错误:地址清理程序:未知地址上的 SEGV(pc 0x00000040133f bp 0x7ffda71a6be0 sp 0x7ffda71a6bb0 T0)= =1==该信号是由 READ 内存访问引起的。 ==1==提示:此故障是由取消引用高值地址引起的(请参阅下面的寄存器值)。拆卸提供的电脑以了解使用了哪个寄存器。我知道这在我的 Mac 上不是问题,内存检查出来了,我也发现了我的问题,当我在几分钟内回答我自己的问题时,你会看到。
-
@DragonAngeltheOriginal 在线 AddressSanitizer 还显示了一个以
ptrList->tail = ptrNewNode;结尾的调用链和一个堆缓冲区溢出。 “我知道这在我的 Mac 上不是问题”——这只是未定义行为的标志。
标签: c linked-list swap singly-linked-list