如何在传递引用而不是指针时为链接列表分配内存?
例如:
struct node {
string info;
node *next;
};
void add(node &aNode){
//if I use
node *newNode;
newNode = new node;
aNode.next = newNode; //aNode.next = newNode; doesn't work either
//allocating on heap seems to give segmentation error.
}
int main() {
node *aNode;
aNode = new node;
add (aNode);
}
Compiler error: error: invalid initialization of reference of type ‘node&’ from expr
或者如果我使用
int main() {
node aNode;
add (aNode);
add (aNode);
aNode.next->next->info = "abc";
string a = aNode.next->next->info;
}
这会给出分段错误。
那么可以仅为其链接列表分配参考吗? (这是C ++)
答案 0 :(得分:3)
应该是
node * newNode = new node;
aNode.next = newNode
您必须手动处理删除,例如检查aNode.next
是否已被占用(如果是,则删除)。
此外,add
函数签名应为:
void add(node & aNode) { ... }
顺便说一句,STL带有一个很好的<forward_list>
; - )
很难说你实际上在问什么,但是按照问题标题,你可能会想到一个像这样的节点结构:
struct Node {
Node & next;
/* payload data */
Node(Node & n) : next(n) /* ... */ { }
};
这样的节点将“通过引用”存储其后继者;但你必须用现有节点初始化它! (没有“null”引用这样的东西。)Poultry-Oval Impasse,你不能这样做。
好的,当你继续拒绝发布你的完整代码时,这是我几乎文字的代码复制/粘贴,对我来说很好用:
更新:我正在添加一项功能,可以在最后添加一个节点,您可能需要这样做。
#include <string>
struct node {
std::string info;
node *next;
node(std::string i = "") : info(i), next(NULL) { }
};
void add(node &aNode)
{
node *newNode;
newNode = new node;
aNode.next = newNode;
}
void add_at_end(node &aNode, std::string value = "")
{
node *newNode, *n = &aNode;
while (n->next) n = n->next; // move to the end
newNode = new node(value);
n->next = newNode;
}
int main()
{
node aNode, bNode;
add(aNode);
add_at_end(bNode, "Hello");
add_at_end(bNode, "World");
add_at_end(bNode, "!");
}
使用g++ -o prog prog.cpp -W -Wall -pedantic
进行编译。
最后,这是STL实现同样目标的方式:
#include <forward_list>
#include <string>
int main() {
std::forward_list<std::string> bList;
bList.push_front("Hello");
bList.push_front("World");
bList.push_front("!");
}
答案 1 :(得分:2)
在main()
的第二个版本中,您要拨打add(aNode)
两次。但是你每次都提供相同的参数。因此,虽然您正在创建两个新的node
对象,但其中一个永远丢失(内存泄漏)。而aNode.next
最终指向另一个。 aNode.next->next
不是有效指针,因此当您尝试通过它访问某些内容时会出现seg-fault。
根据您想要达到的目标,您可以尝试:
node aNode;
add(aNode); // Basically does: aNode.next = new node;
add(*aNode.next); // Basically does: aNode.next->next = new node;
有更好的方法来进行链表,但这至少可以避免seg-fault。
答案 2 :(得分:1)
尝试
int main() {
node *aNode;
aNode = new node;
add (*aNode);
}
你必须传递对象的引用,而不是指针。
我检查了你的代码,在堆栈上分配时没有出现分段错误:http://ideone.com/gTRIG。
我的主张:
#include <string>
using namespace std;
struct node {
string info;
node *next;
node(string str): info(str), next(NULL) {}
~node() { if(next != NULL) delete next; }
node *add(string info){
node *newNode = new node(info);
return aNode.next = newNode;
}
};
int main(){
node rootNode("My rootnode");
node *nxt = rootNode.add("Next node");
nxt->add("Last node");
// No need to call delete, because destructor will clear heap
}