当我将字符串放入节点>名称时,为什么会出现分段错误(核心转储)?



当我getline(cin, node->name)时分段错误(核心转储)。

我通过在输入函数中声明一个str字符串来修复,然后node->name = str.但是跑到线cin >> node->year,仍然遇到分段错误。

struct client
{
int code;
string name;
int year;
float maths, physics, chemistry;
struct client *next;
};
struct client* input()
{
struct client *node = (struct client *)malloc(sizeof(struct client));
cout << "Code: ";
cin >> node->code;
cout << "Name: ";
cin.ignore();
getline(cin, node->name);
cout << "Year: ";
cin >> node->year;
cout << "Maths, Physics, Chemistry: ";
cin >> node->maths >> node->physics >> node->chemistry;
node->next = NULL;
return node;
}

由于您使用malloc来分配内存,因此新node中的任何内容都不会被初始化。特别是string name将无法正确初始化,这将在您尝试使用它时导致问题,因为涉及它的任何功能都依赖于字符串已正确构造的事实。取而代之的是:

struct client *node = (struct client *)malloc(sizeof(struct client));

这样做:

client *node = new client;

这样node(和name)就可以正确初始化。

正如注释所暗示的那样,您的string可能指的是std::string,这是一个非 POD 类。这意味着您需要调用构造函数等来使用该对象,而不仅仅是分配内存。

这意味着您必须改为执行以下操作:

client *node = new node;

同样,要销毁它:

delete node;

或者,最好使用 RAII 指针类型,如 C++11 中的std::unique_ptr

std::unique_ptr<client> = std::make_unique<client>();

除了其他答案中已经提到的选择之外,我们还有两种选择。


建议的方法是重构代码并避免动态分配。 改用自动变量并移动语义。

client input()
{
client node;
// ... do input
return node;
}

(您可以直接使用client代替struct client)

这是 C++ 中的首选方法。


如果你坚持malloc,那么通过 placement-new 显式调用构造函数:

client* node = (client*) malloc(sizeof(client));
new (node) client{};

当你free它时,记得调用析构函数:

node->~client();
free(node);

这种方法非常容易出错且违反直觉 并且强烈建议不要这样做。

相关内容

  • 没有找到相关文章

最新更新