作为c ++的新角色,我试图了解使用New的原因和位置。 所以我试图在这个链接的List例子中不使用New,
////////////////////////////////////////////////////////////////
struct link //one element of list
{
int data; //data item
link* next; //pointer to next link
};
////////////////////////////////////////////////////////////////
class linklist //a list of links
{
private:
link* first; //pointer to first link
public:
linklist() //no-argument constructor
{ first = NULL; } //no first link
void additem(int d); //add data item (one link)
void display(); //display all links
};
//--------------------------------------------------------------
void linklist::additem(int d) //add data item
{
link* newlink = new link; //make a new link
newlink->data = d; //give it data
newlink->next = first; //it points to next link
first = newlink; //now first points to this
}
//--------------------------------------------------------------
void linklist::display() //display all links
{
link* current = first; //set ptr to first link
while( current != NULL ) //quit on last link
{
cout << current->data << endl; //print data
current = current->next; //move to next link
}
}
////////////////////////////////////////////////////////////////
int main()
{
linklist li; //make linked list
li.additem(25); //add four items to list
li.additem(36);
li.additem(49);
li.additem(64);
return 0;
}
以下内容:
////////////////////////////////////////////////////////////////
struct link //one element of list
{
int data; //data item
link* next; //pointer to next link
};
////////////////////////////////////////////////////////////////
class linklist //a list of links
{
private:
link first; //pointer to first link
public:
linklist() //no-argument constructor
{ first = NULL; } //no first link
void additem(int d); //add data item (one link)
void display(); //display all links
};
//--------------------------------------------------------------
void linklist::additem(int d) //add data item
{
link newlink; //make a new link
newlink.data = d; //give it data
newlink.next = first; //it points to next link
first = newlink; //now first points to this
}
//--------------------------------------------------------------
void linklist::display() //display all links
{
link current = first; //set ptr to first link
while( current != NULL ) //quit on last link
{
cout << current.data << endl; //print data
current = current.next; //move to next link
}
}
////////////////////////////////////////////////////////////////
int main()
{
linklist li; //make linked list
li.additem(25); //add four items to list
li.additem(36);
li.additem(49);
li.additem(64);
return 0;
}
但这不起作用。在我继续尝试之前,我想知道这个特定的例子是否必须坚持使用New,而不使用它就无法完成。
答案 0 :(得分:2)
无法在没有new
或某种形式的动态内存分配的情况下创建链接列表,因为您无法创建指向堆栈的永久节点。
但是,幸运的是,您不必自己编写容易出错的new
代码,因为C ++已经为您提供了一个方便的std::list
类。另外,在C ++ 11中提供了单独链接的forward_list
。
答案 1 :(得分:2)
我认为你不了解堆栈内存与堆内存。你应该做的是“动态分配”。
如果您将变量定义为link newlink;
你只在堆栈上创建它,这意味着当你退出你的函数时它不再存在,它被“解除分配”。该列表所需的是请求在完成功能时未释放的新内存区域。为此,您需要使用动态分配。其中一种方法是new
运算符。另一种规范的做法是malloc函数。
TL; DR你不能按照你想要的方式去做,你似乎误解了C / C ++中的内存是如何工作的。您 使用指针和动态分配,这就是他们称之为动态链接列表的原因。
另外,不要使用std:list作为你的问题,你编写代码的方式指向我,链表实现是各种各样的功课。在跑向其他人的实施之前,先学习理解基本功能。
答案 2 :(得分:0)
通过此行动
first = newlink;
您在旧数据上记录数据。
您只有一个linklist
类字段,并在上面的每个操作都覆盖数据。
当您使用new
时,它会在堆中(在linklist
之外)分配实例,并且这些实例(link
)通过指针相互连接。在你的第二段代码中,它没有发生,你在内存中只有一个link
的实例。
答案 3 :(得分:0)
链接列表本质上是各个动态分配的块的集合,因此new
是一个要求,无论它是否暴露给客户端代码。正如@Alok建议的那样,std::list
更可取,因为它封装了这个内存分配并确保不会发生泄漏等。你在堆栈上分配newLink
的尝试将无法编译,除非你取其地址,您当然不想这样做(因为newLink
将在函数返回后立即从堆栈中弹出。)
答案 4 :(得分:0)
当你说
时link newlink; //make a new link
你已经在堆栈上建立了一个超出范围的链接。
我认为你应该使用规则“避免原始指针”,而不是避免新的。如果你使用std :: make_shared,并保持std :: unique_ptr而不是原始指针,这可能是一个有用的学习练习。
答案 5 :(得分:0)
要解决您的问题,您必须先了解以下内容:
有许多文档深入解释了堆栈是什么。但非常简化的堆栈内存是临时内存,只能在c ++的范围内使用。例如:
int* p;
{
int a; //Create a variable in stack memory
a = 10; //Assing stack memory
p = &a; //Create a pointer to stack memory
} //Variable a is released since the scope has ended
printf("%d",*p); //The pointer now points to released memory. Probably it will not be 10
这同样适用于以下功能:
void suma()
{
int a; //This variable will only exists for this function
}
您正在做的是创建和复制稍后将在函数结束时释放的变量。
link first; //pointer to first link
void linklist::additem(int d) //add data item
{
link newlink; //I'll only exists in this function
newlink.data = d;
newlink.next = first; //Does even this compiles???
first = newlink; //After the function sends first will point to a released memory. Aren't you missing a & operator ? &newlink
}
您需要将链接节点存储在某处。新运营商为您做到了这一点。但如果你不想使用它。您可以将其存储在静态存储器中。
例如,你可以有两个这样的静态变量:
link staticLinks[100];
int lastUsedLink = 0;
在整个程序执行期间不会释放此内存,因此您可以执行以下操作:
void linklist::additem(int d) //add data item
{
staticLinks[lastUsedLink].data = d; //Now this data will no dissapear
lastUsedLink[lastUsedLink].next = first; //Point to the last element
first = &lastUsedLink[lastUsedLink]; //No this becomes the last element
lastUsedLink++; //Use the next element of the array for the next addition
}
它非常容易改进。例如,您可以添加一个防护,以避免使用101或更多数组元素。但现在你可能会理解这个问题了。
////////////////////////////////////////////////////////////////
struct link //one element of list
{
int data; //data item
link* next; //pointer to next link
};
link staticLinks[100];
int lastUsedLink = 0;
////////////////////////////////////////////////////////////////
class linklist //a list of links
{
private:
link* first; //pointer to first link
public:
linklist() //no-argument constructor
{ first = NULL; } //no first link
void additem(int d); //add data item (one link)
void display(); //display all links
};
//--------------------------------------------------------------
void linklist::additem(int d) //add data item
{
staticLinks[lastUsedLink].data = d; //give it data
lastUsedLink[lastUsedLink].next = first; //it points to next link
first = &lastUsedLink[lastUsedLink]; //now first points to this
lastUsedLink++;
}
//--------------------------------------------------------------
void linklist::display() //display all links
{
link current = first; //set ptr to first link
while( current != NULL ) //quit on last link
{
cout << current.data << endl; //print data
current = current.next; //move to next link
}
}
////////////////////////////////////////////////////////////////
int main()
{
linklist li; //make linked list
li.additem(25); //add four items to list
li.additem(36);
li.additem(49);
li.additem(64);
return 0;
}