【问题标题】:C++ : Segmentation fault (core dumped) On linux OSC ++:Linux操作系统上的分段错误(核心转储)
【发布时间】:2016-11-19 19:14:16
【问题描述】:

我正在尝试使用 g++ 5.1 编译和执行这个小 c++ 代码,它编译得很好,当我在 linux 上执行它时,我收到这个错误消息:“Segmentation fault (core dumped)”。

但是相同的代码在 osx 上可以正常运行,但在 linux 上却不行:

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <string.h>
using namespace std;

struct node {
 std::string data;
};

int main() {
  struct node * node = (struct node * )
  malloc(sizeof(struct node));

  node->data.assign("string");
  // node->data = "string" --> same issue

  return 0;
}

我尝试了一个简单的分配 (node->data = "string"),但我遇到了同样的问题任何帮助!

【问题讨论】:

  • 为什么在 C++ 代码中使用mallocnew 将初始化字符串对象 - malloc 不会。
  • 谁一直在教这种东西?那些人难道没有想到80年代已经结束了吗? ://
  • 扩展@EdHeal 所说的内容:仅分配 sizeof(struct node) 字节然后开始使用它们是不够的。您必须确保字符串对象的构造函数也运行,以便正确初始化节点对象的私有状态。为此,您需要使用 new 运算符(例如 node = struct node * node = new node; )
  • 顺便说一句,看看链接的问题,它可能不是一个骗局,但至少高度相关。
  • 在编程中,“代码”从不使用“s”复数。你会永远说“代码”。 (当人们这样做时,它在语法上是不正确的)

标签: c++ pointers memory allocation assign


【解决方案1】:

用 C++ 忘记malloc()。如果要分配对象,请使用new

node * n = new node;   // or if your variable should be called node 
                       // you'd need new struct node to disambiguate

malloc() 的问题在于它只是分配了未初始化的内存。它不能确保对象创建的 C++ 语义。因此,节点内的字符串未初始化为有效状态。这会导致该字符串的分配为 UB。

如果您确实需要在 C++ 中使用 malloc(),则需要在之后使用 placement new 将对象初始化为有效状态 (online demo)。

 void *p = malloc(sizeof(node));   // not so a good idea ! 
 node *n2 = new (p)node;           // but ok, it's feasible. 

【讨论】:

  • 为什么必须初始化字符串,因为他正在用“字符串”替换其中的任何内容......还有新的如何确保调用字符串的构造函数?
  • @solti 这就是new 所做的,它分配内存并调用构造函数。
  • @GillBates 因为没有构造字符串(因为没有为字符串调用构造函数)这就是段错误的原因?
  • @solti 是的,假装分配的内存是一个字符串对象并将其用作一个对象是未定义的行为
  • 请注意,使用placement new 需要程序员在对象的生命周期结束时显式调用对象的析构函数。
【解决方案2】:

你不能 malloc 一个 C++ 字符串。您至少应该使用正确的newdelete,以便调用构造函数。停止在 C++ 中使用 C。

理想情况下你甚至不会使用new;只要有一个具有自动存储持续时间的普通对象,或者,如果您迫切需要动态分配,std::make_unique

2016 年无需手动管理内存。

【讨论】:

  • There is no need for manual memory management in 2016. 我想我可以扔掉我的自定义分配器.. :(
  • @Lightness Races in Orbit:你的意思是智能指针接管手动内存管理?
  • @GillBates:这不算;)
  • @GillGates:使用分配器的代码不使用手动内存管理。 IOW,您在较低级别上将自动化掌握在自己手中,但在较高级别上仍然是自动的。
猜你喜欢
  • 1970-01-01
  • 2014-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
  • 2017-02-25
  • 2016-07-12
相关资源
最近更新 更多