我的问题是,当试图添加到数组中的链表时,它似乎不起作用,我几乎完全不知道为什么会这样。首先,我声明对象move
,如下所示:
struct move {
move(int startX, int startY, int endX, int endY)
{
this->startX = startX;
this->startY = startY;
this->endX = endX;
this->endY = endY;
this->next = nullptr;
}
move()
{
next = nullptr;
this->startX = -1;
}
int startX;
int startY;
int endX;
int endY;
move* next;
};
然后我声明了2个数组,一个包含100个move
对象的链表,另一个包含指向第一个数组中每个链表中元素的指针。如下所示:
move possibleMoves[100];
move * endOfLists[100];
然后我将这些数组初始化如下所示:
for (int i = 0; i < 100; i++) {
possibleMoves[i] = move();
endOfLists[i] = &possibleMoves[i];
}
转到函数本身,它添加到possibleMoves
数组中的一个链接列表,我将其原型化为:
void listAdd(move * list, move * object, int width);
我称之为:
if (possibleMoves[0].startX == -1) {
possibleMoves[0] = *(new move(x, y, x + xOffset, y + yOffset));
}else {
listAdd(endOfLists[width], new move(x, y, x + xOffset, y + yOffset), width);
}
该函数声明如下:
void listAdd(move * list, move * object, int width) {
int count = 0;
while (list->next != nullptr){
count++;
list = (*list).next;
}
std::cout << "\nCount: " << count << std::endl;
list->next = object;
endOfLists[width] = list->next;
}
计数总是输出为'0'。
这是所有代码(https://pastebin.com/E5g58N6L)的链接,它并不漂亮。在第188,197和444行调用listAdd
过程。这是MCVE:
#include<stdio.h>
#include <stdlib.h>
#include<math.h>
#include<iostream>
struct move {
move(int startX, int startY, int endX, int endY)
{
this->startX = startX;
this->startY = startY;
this->endX = endX;
this->endY = endY;
this->next = nullptr;
}
move()
{
next = nullptr;
this->startX = -1;
}
int startX;
int startY;
int endX;
int endY;
move* next;
};
void listAdd(move * list, move * object, int width);
move possibleMoves[100];
move * endOfLists[100];
int main() {
int x = 0;
int y = 0;
int xOffset = 1;
int yOffset = 1;
int width = 0;
for (int i = 0; i < 100; i++) {
possibleMoves[i] = move();
endOfLists[i] = &possibleMoves[i];
}
if (possibleMoves[0].startX == -1) {
possibleMoves[0] = *(new move(x, y, x + xOffset, y + yOffset));
}else {
listAdd(endOfLists[width], new move(x, y, x + xOffset, y + yOffset), width);
}
void listAdd(move * list, move * object, int width) {
int count = 0;
while (list->next != nullptr)
{
count++;
list = (*list).next; //Go down the list until it reaches an item with nothing next.
}
std::cout << "\nCount: " << count << std::endl;
list->next = object;
endOfLists[width] = list->next;
}
答案 0 :(得分:1)
NM完整代码。您没有告诉我们初始width
是什么,但假设它有效(即-1<width<100
),则无关紧要。看看这里发生了什么(添加功能结束):
list->next = object;
此时list
endOfLists[width]
。现在,你正确地设置了新对象的下一个,到目前为止一直很好。
但现在呢?
endOfLists[width] = list->next;
那么保存在全局中的“head”指针(为什么?)绕过它最初指向的(谁有一个正确的next
!)并直接指向一个后代,新的对象为NULL 。我猜这不是你想要的:
基本上你是在交换头部指针,同时泄漏记忆。你想要:
object->next=endOfLists[width]
,然后将第二行设置为endOfLists[width]=object
,使列表反转。另外:
delete
所有new
个对象。修改强>
我看到了你的添加 - 第一次调用将始终返回0 ,因为所有初始对象都具有NULL nexts,即使你修复了代码。您需要至少两次调用同一索引(width
)才能开始测试。
图形附录
一开始我们有100个对象,存储在一个数组中,所有这些都看起来像这样:
head->list->NULL
list
这是endOfLists
在某个索引处指向的对象,我们称之为指针head
。现在,我们要添加新对象。我们输入加法函数,第一个参数为endOfLists[width]
,所以这将是函数本身的list
参数。
我们立即跳过while(因为我们的下一个已经是NULL)。到达上面的第一行,我们现在将头部连接到新对象:
list->object->NULL
所以在数组中我们有:
head->list->object->NULL
同样,head
是存储在endOfLists[width]
中的指针。现在我们告诉endOfLists[width]
将头部交换到另一个头部,将其设置为list->next
,这是对象。那么我们的记忆是怎样的呢?
head->object->NULL
list->^
head
(数组单元格)和list
都指向对象,没有任何内容指向list
。我们在那里泄漏。下次我们用更新的单元格调用函数时,我们将重复该过程,泄漏对象:
head-> object2->NULL
list->object->^
等等。