迭代时列表结构发生变化
List structure changing while iterating
我正在使用以下代码迭代链表
void display()
{
if (head == NULL)
{
printf("\n");
return;
}
struct node *current = head;
while (current->next != NULL)
{
printf("%3c", current->data); // *(current).data
current = current->next; // current = *(current).next;
} //printf( "\n" );
printf("%3c", current->data);
printf(" <--> ");
while (current != NULL)
{
printf("%3c", current->data); // *(current).data
current = current->prev; // current = *(current).prev;
}
printf("\n");
}
我在这个函数中遇到了分段错误,我无法计算
为什么会发生这种情况。
我 运行 调试器并截取了屏幕截图:
以上两张图是在迭代时调用显示
在 while 循环中。奇怪的是在第一张图片
元素是 Y->O->R->x->K
而当迭代在 while 循环中继续时
遇到R
下一个数据是st运行gely some[=13=]0
我从来没有插入那个,它是如何改变的
相同的迭代,因为没有修改发生
最小可重现代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 50
#define MAX_LEN 30
char get(int index);
int search(char);
struct twoInts
{
int int1;
int int2;
};
struct node
{ // list 'node' struct
char data;
struct node *next;
struct node *prev;
};
void init();
void display();
struct node *head;
int main()
{
int index;
char key;
struct twoInts *arr[MAX_LEN];
char buffer[BUFFER_SIZE];
init();
int i = 0;
int summation[10] = {89, 79, 82, 75, 85, 76, 65, 66, 83};
for (; i < 8; i++)
{
int sum = summation[i];
insert((char)sum);
display();
}
char removeList[] = {'B', 'S', 'A', 'O', 'R', 'K', 'Y', 'U', 'L', '[=11=]'};
i = 0;
// insert again
char addList[] = "ZPSLVMBCT";
i = 0;
while ((key = addList[i]) != '[=11=]')
{
insert(key);
display();
i++;
}
key = 'x';
index = 2;
insertAfter(key, index);
printf(xyz-1\n");
int length = len();
printf("xyz-2\n");
// printf("\ninsert %c after index %d: (%d)\n", key, index, length);
display();
}
/* Initialize the list. */
void init()
{
head = NULL;
}
int len()
{
struct node *tmp = head;
int length = 0;
while (tmp != NULL)
{
length++;
tmp = tmp->next;
}
return length;
}
/* Print the content of the list. */
void display()
{
if (head == NULL)
{
printf("\n");
return;
}
struct node *current = head;
while (current->next != NULL)
{
current = current->next; // current = *(current).next;
} //printf( "\n" );
while (current != NULL)
{
current = current->prev; // current = *(current).prev;
}
}
void insert(char c) // at the end
{
/* special case: list is empty, need to change head */
if (head == NULL)
{ /* the list is empty */
head = malloc(sizeof(struct node));
head->data = c;
head->next = NULL;
head->prev = NULL;
}
else
{
struct node *tmp = head;
while (tmp->next != NULL)
tmp = tmp->next;
struct node *last = malloc(sizeof(struct node));
last->data = c;
last->next = NULL;
last->prev = tmp;
tmp->next = last;
}
}
void insertAfter(char c, int index)
{
struct node *tmp = head;
int currIndex = 0;
while (tmp->next != NULL)
{
if (currIndex == index)
break;
currIndex++;
tmp = tmp->next;
}
if (currIndex == index)
{
struct node *newNode = malloc(sizeof(struct node));
newNode->data = c;
newNode->prev = tmp;
newNode->next = tmp->next;
struct node *nextNode = tmp->next;
if (tmp->next != NULL)
{
tmp->next = &newNode;
nextNode->prev = &newNode;
}
}
}
好的,我已经解决了你的问题。问题出在您声明 struct node newNode
的 insertAfter
函数中。这会在 堆栈 上创建一个对象,而列表的其余部分存储在 堆 上。当 insertAfter
函数退出时,这会导致堆栈展开并且内存无法访问。您应该将此行替换为对 malloc
.
的调用
我正在使用以下代码迭代链表
void display()
{
if (head == NULL)
{
printf("\n");
return;
}
struct node *current = head;
while (current->next != NULL)
{
printf("%3c", current->data); // *(current).data
current = current->next; // current = *(current).next;
} //printf( "\n" );
printf("%3c", current->data);
printf(" <--> ");
while (current != NULL)
{
printf("%3c", current->data); // *(current).data
current = current->prev; // current = *(current).prev;
}
printf("\n");
}
我在这个函数中遇到了分段错误,我无法计算
为什么会发生这种情况。
我 运行 调试器并截取了屏幕截图:
以上两张图是在迭代时调用显示
在 while 循环中。奇怪的是在第一张图片
元素是 Y->O->R->x->K
而当迭代在 while 循环中继续时
遇到R
下一个数据是st运行gely some[=13=]0
我从来没有插入那个,它是如何改变的
相同的迭代,因为没有修改发生
最小可重现代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 50
#define MAX_LEN 30
char get(int index);
int search(char);
struct twoInts
{
int int1;
int int2;
};
struct node
{ // list 'node' struct
char data;
struct node *next;
struct node *prev;
};
void init();
void display();
struct node *head;
int main()
{
int index;
char key;
struct twoInts *arr[MAX_LEN];
char buffer[BUFFER_SIZE];
init();
int i = 0;
int summation[10] = {89, 79, 82, 75, 85, 76, 65, 66, 83};
for (; i < 8; i++)
{
int sum = summation[i];
insert((char)sum);
display();
}
char removeList[] = {'B', 'S', 'A', 'O', 'R', 'K', 'Y', 'U', 'L', '[=11=]'};
i = 0;
// insert again
char addList[] = "ZPSLVMBCT";
i = 0;
while ((key = addList[i]) != '[=11=]')
{
insert(key);
display();
i++;
}
key = 'x';
index = 2;
insertAfter(key, index);
printf(xyz-1\n");
int length = len();
printf("xyz-2\n");
// printf("\ninsert %c after index %d: (%d)\n", key, index, length);
display();
}
/* Initialize the list. */
void init()
{
head = NULL;
}
int len()
{
struct node *tmp = head;
int length = 0;
while (tmp != NULL)
{
length++;
tmp = tmp->next;
}
return length;
}
/* Print the content of the list. */
void display()
{
if (head == NULL)
{
printf("\n");
return;
}
struct node *current = head;
while (current->next != NULL)
{
current = current->next; // current = *(current).next;
} //printf( "\n" );
while (current != NULL)
{
current = current->prev; // current = *(current).prev;
}
}
void insert(char c) // at the end
{
/* special case: list is empty, need to change head */
if (head == NULL)
{ /* the list is empty */
head = malloc(sizeof(struct node));
head->data = c;
head->next = NULL;
head->prev = NULL;
}
else
{
struct node *tmp = head;
while (tmp->next != NULL)
tmp = tmp->next;
struct node *last = malloc(sizeof(struct node));
last->data = c;
last->next = NULL;
last->prev = tmp;
tmp->next = last;
}
}
void insertAfter(char c, int index)
{
struct node *tmp = head;
int currIndex = 0;
while (tmp->next != NULL)
{
if (currIndex == index)
break;
currIndex++;
tmp = tmp->next;
}
if (currIndex == index)
{
struct node *newNode = malloc(sizeof(struct node));
newNode->data = c;
newNode->prev = tmp;
newNode->next = tmp->next;
struct node *nextNode = tmp->next;
if (tmp->next != NULL)
{
tmp->next = &newNode;
nextNode->prev = &newNode;
}
}
}
好的,我已经解决了你的问题。问题出在您声明 struct node newNode
的 insertAfter
函数中。这会在 堆栈 上创建一个对象,而列表的其余部分存储在 堆 上。当 insertAfter
函数退出时,这会导致堆栈展开并且内存无法访问。您应该将此行替换为对 malloc
.