我做了一个代码,我要在其中打印一个简单的链接列表,列表的信息包含人名和号码电话。不幸的是,当我打印我的列表时,只有我读过的最后一个人的姓名,但电话号码不同。我不知道为什么我的代码不起作用。
所以,这是我的代码
#pragma once
struct Nodd{
int phone;
char *name;
Nodd *next;
};
void InsertList(Nodd *&L,int nr,char *n);
void PrintList(Nodd *&L);
#include <iostream>
#include "Header.h"
using namespace std;
void InsertList(Nodd *&L,int nr, char *n){
Nodd *p = new Nodd;
p->name = n;
p->phone = nr;
p->next = L;
L = p;
}
void PrintList(Nodd *&L){
Nodd *p = L;
while(p){
cout << p->name << " " << p-> phone << endl;
p = p->next;
}
}
#include <iostream>
#include "Header.h"
using namespace std;
int main(){
Nodd *L = 0; //L = first element of the linked list
int nr, i, t;
char *n;
n = new char;
cout <<"Read number of people: ";
cin >> t;
for(i = 0; i < t; i++){
cout << "Name: ";
cin.ignore(50, '\n');
cin.getline(n, 50);
cout << "Phone number: ";
cin >> nr;
InsertList(L, nr, n);
}
PrintList(L);
return 0;
}
我编译的是:
阅读人数:2
Name: Elena
Phone number: 99776244
Name: Andreea
Phone number: 98776489
............................
Andreea 98776489
Andreea 99776244
你能帮我解决一下如何修复我的代码吗?
答案 0 :(得分:0)
您的代码中有很多错误:
char *n;
n = new char; // A single dynamic character
后来:
cin.getline(n, 50); UB here
正如您所看到的,为单个字符变量分配50个字符,因此它是一个未定义的行为。
要纠正它:
char* n = new char[50];
如果你仔细看看你看到的输出:
Andreea 98776489 Andreea 99776244
同名,但整数值是正确的!所以你的插入节点功能是正确的,但问题是关于名称。为什么呢?
在插入节点中编写:
p->name=n; // That is not the way you should do it.
纠正于:
p->name = new char[strlen(n) + 1];
strcpy(p->name, n);
您必须为每个不共享同一节点的节点分配内容name
。
此外,当您完成动态内存时,必须释放并清理以避免内存泄漏:
delete[] n;
添加一个函数来释放成员名称的所有节点的内存:
void FreeupMemory(Nodd*& L){
Nodd* pTmp = L;
while(pTmp){
delete[] pTmp->name;
pTmp = pTmp->next;
}
}
在主要打印后节点数据释放内存:
FreeupMemory(L);
我的建议:只要C ++为您提供了许多强大的类,实用程序就会放弃使用动态数组,因此您可以使用class string
,vector
。这真的很好,不介意内存泄漏。
请相信我,如果您的成员数据name
是一个字符串类对象,您就不会陷入这样容易出错的状态。
struct Nodd{
int phone;
std::string name;
Nodd *next;
};
void InsertList(Nodd *&L,int nr, std::string n){
// your code
p->name = n; // ok
// ...
}
主要:
std::string n;
for(int i(0); i < t; i++){
std::getline(std::cin, n);
}
**还有一件坏事:
为什么要包含标题? “递归包容”?
你可以创建一个头文件“header.h”只包含类接口和函数的原型和另一个源文件“MyLinkedList.cpp” 包括标题。和main.cpp。
// header.h
#pragma once
struct Nodd{
int phone;
char *name;
Nodd *next;
};
void InsertList(Nodd *&L,int nr,char *n);
void PrintList(Nodd *&L);
void FreeupMemory(Nodd*&L);
// MyLinkedList.cpp
#include "header.h"
#include <iostream>
using namespace std;
void InsertList(Nodd*& L, int nr, char* n){
Nodd *p = new Nodd;
p->name = n;
p->phone = nr;
p->next = L;
L = p;
}
void PrintList(Nodd *&L){
Nodd* p = L;
while(p){
cout << p-> name << " " << p->phone << endl;
p = p->next;
}
}
void FreeupMemory(Nodd*& L){
Nodd* pTmp = L;
while(pTmp){
delete[] pTmp->name;
pTmp = pTmp->next;
}
}
// main.cpp
#include <iostream>
#include "Header.h"
using namespace std;
int main(){
Nodd* L = 0; //L = first element of the linked list
int nr, i, t;
char* n = new char[50];
cout << "Read number of people: ";
cin >> t;
for(int i = 0; i < t; i++){
cout << "Name: ";
cin.ignore(1, '\n');
cin.getline(n, 50);
cout << "Phone number: ";
cin >> nr;
InsertList(L, nr ,n);
}
PrintList(L);
FreeupMemory(L);
delete[] n;
return 0;
}