从函数返回的指针为';无效 我正在帮助一个朋友做一个任务,一个链表的实现,虽然我的C++技巧现在已经生锈了。

从函数返回的指针为';无效 我正在帮助一个朋友做一个任务,一个链表的实现,虽然我的C++技巧现在已经生锈了。,c++,C++,有一些结构 struct Song{ int id; string name; string singerName; }; struct SongNode { Song sg; SongNode *previousNode; SongNode *nextNode; }; struct SongDoublyLinkedList{ SongNode *firstElement; }; 这首短曲主要是 SongDoublyLinkedList* list = new SongDoublyLink

有一些结构

struct Song{
int id;
string name;
string singerName;
};

struct SongNode {
Song sg;
SongNode *previousNode;
SongNode *nextNode;
};

struct SongDoublyLinkedList{
SongNode *firstElement;
};
这首短曲主要是

SongDoublyLinkedList* list = new SongDoublyLinkedList();

SongNode* song1 = new SongNode();

song1->sg.id = 1;
song1->sg.name = "All Night";
song1->sg.singerName = "Parov Stelar";

addSong(list, song1);

SongNode* song2 = new SongNode();

song2->sg.id = 2;
song2->sg.name = "Song 2";
song2->sg.singerName = "Blur";

addSong(list, song2);
然后这两个函数

SongNode *getLastSong(SongDoublyLinkedList *songList)
{
  if (songList->firstElement == NULL) return NULL;

  SongNode currentElement = *(songList->firstElement);

  while (currentElement.nextNode != NULL)
  {
      currentElement = *(currentElement.nextNode);
  }

  return &currentElement;
}

void addSong(SongDoublyLinkedList *songList, SongNode *songNd)
{
  songNd->nextNode = NULL;
  songNd->previousNode = NULL;

  SongNode* lastNode = getLastSong(songList);

  if (lastNode == NULL) songList->firstElement = songNd;
  else lastNode->nextNode = songNd;
}
问题出现在
return¤tElementgetLastSong
中的code>,但我不明白问题是什么。它几乎表现为内存是免费的,但不是。这最初让我觉得我返回了错误的值,但我通过Visual Studio调试器运行了它,指针似乎在
getLastSong
函数中工作正常,但不在其范围之外

价值良好:

值错误:

另外,如果我试图取消对坏的'lastNode'的引用,那么就会出现某种形式的内存访问错误,因此看起来我发送的值确实不正确


我假设我缺少一些愚蠢的东西(或者更可能的是,我已经忘记C++中的一个元素了很多年了),为什么这不是我期望的工作方式?< /P> < P> <代码> CurrestEngult>代码>是自动的(在代码的原始意义上,Auto < /Cord>>关键字,或非静态)对于

getLastSong()
来说是本地变量,因此当该函数返回时,该变量将不再存在

正如aschepler在评论中指出的那样,要扩展声明
SongNode currentElement=*(songList->firstElement)使
currentElement
成为
*(歌曲列表->firstElement)
的副本

currentElement
存在的范围(即作为
*(songList->firstElement)
的副本)在函数中,因此当函数返回时,它不再存在

返回其地址意味着将不存在的对象的地址返回给调用者。如果调用方试图使用该地址(即取消引用),则结果是未定义的行为


你已经在你最初的问题中展示过,以及你在编辑前如何误解我的回答-在你的C理解方面试图解释C++的危险。C和C++是非常不同的语言,即使它们有句法相似性。这是一个区域,即使代码看起来很相似,它的行为也非常不同。

currentElement
是一个自动变量(在
auto
关键字或非静态的原始意义上),它是
getLastSong()
的局部变量,因此当该函数返回时就不再存在

正如aschepler在评论中指出的那样,要扩展声明
SongNode currentElement=*(songList->firstElement)使
currentElement
成为
*(歌曲列表->firstElement)
的副本

currentElement
存在的范围(即作为
*(songList->firstElement)
的副本)在函数中,因此当函数返回时,它不再存在

返回其地址意味着将不存在的对象的地址返回给调用者。如果调用方试图使用该地址(即取消引用),则结果是未定义的行为



你已经在你最初的问题中展示过,以及你在编辑前如何误解我的回答-在你的C理解方面试图解释C++的危险。C和C++是非常不同的语言,即使它们有句法相似性。这是一个区域,即使代码看起来很相似,它的行为也非常不同。

但是
currentElement
不是指向该函数之外的内存地址吗?@cost No,因为它不是指针<代码>歌曲节点currentElement=*(歌曲列表->第一元素)
制作
歌曲节点的本地副本
<代码>歌曲节点*currentElement=songList->firstElement
将创建一个指向长期节点的指针,可能对该函数更有用。@aschepler啊,我没有意识到它在那个实例中复制了一个,谢谢you@aschepler我想我陷入了一种C#心态,认为一切都是参考,我可以在
SongNode
SongNode*
之间不加区别地来回移动,谢谢你让我直截了当。这就是我想要的答案needed@cost由于这似乎回答了您的问题,请将其标记为答案。:-)但是,
currentElement
不是指向该函数之外的内存地址吗?@cost否,因为它不是指针<代码>歌曲节点currentElement=*(歌曲列表->第一元素)
制作
歌曲节点的本地副本
<代码>歌曲节点*currentElement=songList->firstElement将创建一个指向长期节点的指针,可能对该函数更有用。@aschepler啊,我没有意识到它在那个实例中复制了一个,谢谢you@aschepler我想我陷入了一种C#心态,认为一切都是参考,我可以在
SongNode
SongNode*
之间不加区别地来回移动,谢谢你让我直截了当。这就是我想要的答案needed@cost由于这似乎回答了您的问题,请将其标记为答案。:-)@RaymondChen,但是currentElement不是指向存在于该函数之外的内存地址吗,即在main中创建的SongNode?还是我把自己搞糊涂了somewhere@RaymondChen与其说是问题的复制品,不如说是我误解了C++如何工作,在这里,你使用<代码> STD::MAP<代码>或<代码> STD::列表< /C> >而不是导出你自己的数据结构?这些已经过调试,因此您不必浪费时间重写和测试它们。@ThomasMatthews我正在帮助一位朋友完成一项编程任务,即制作一个链表。@RaymondChen但是currentElement不是指向该函数之外的内存地址吗,即在main中创建的SongNode?还是我弄糊涂了