【问题标题】:Segmentation fault when calling "new" in c++?在 C++ 中调用“new”时出现分段错误?
【发布时间】:2011-09-06 23:17:14
【问题描述】:

尝试调用“new”来创建指针并将其推入向量时出现段错误。我在向量中推送元素的代码是:

queue->push_back(new Box(gen_id, Interval(x_mid, x_end), Interval(y_mid-y_halfwidth, y_mid+y_halfwidth)));

基本上,Box 是一个类,构造函数只接受 3 个参数,generation_id 和 2 个Intervals。我在这个“推送”之前和之后打印出了向量中的内容, 之前:

[ -0.30908203125, -0.3087158203125 ] , [ -0.951416015625, -0.9510498046875 ]
[ -0.3087158203125, -0.308349609375 ] , [ -0.951416015625, -0.9510498046875 ]
[ -0.30908203125, -0.3087158203125 ] , [ -0.9510498046875, -0.95068359375 ]
[ -0.3087158203125, -0.308349609375 ] , [ -0.9510498046875, -0.95068359375 ]

之后:

[ -0.30908203125, -0.3087158203125 ] , [ -0.951416015625, -0.9510498046875 ]
[ -0.3087158203125, -0.308349609375 ] , [ -0.951416015625, -0.9510498046875 ]
[ 8.9039208750109844342e-243, 6.7903818933216500424e-173 ] , [ -0.9510498046875, -0.95068359375 ]
[ -0.3087158203125, -0.308349609375 ] , [ -0.9510498046875, -0.95068359375 ]
[ -0.3087158203125, -0.308349609375 ] , [ -0.95123291015625, -0.95086669921875 ]

我不知道为什么会发生这种情况,但显然,有一个元素已损坏。除了“push”之外,这两组输出之间没有其他代码,我使用gdb来确认。另外,我检查了这 2 个Intervals 变量,它们都给了我一个有意义的结果。

我的问题是:“新”在什么情况下会出现段错误?还是我的问题是由于其他原因引起的?谢谢。

【问题讨论】:

  • 段错误什么时候发生?请告诉我们Box的代码。
  • 你为什么要推指针?
  • 我不认为 new 通常可以分段。我会寻找堆栈损坏,从Box(int, Interval, Interval)Interval(int, int)Intervals 复制/移动构造函数/操作符开始
  • @Moo, new 如果存在堆损坏,可能会出现段错误。
  • @Henning Makholm:如果存在堆损坏,任何事情都可能发生。 stackoverflow.com/questions/2766731/…,是的。仍然:可能是数组边界或指针错误。

标签: c++ segmentation-fault new-operator allocation


【解决方案1】:

假设确实是 new 生成了段错误,最常见的原因是堆损坏,通常是由于覆盖了您不拥有的内存和/或双重删除。

如果您可以在 Linux 系统上运行,Valgrind 将成为您的朋友。

【讨论】:

    【解决方案2】:

    我怀疑new 本身是否会给您带来段错误;问题可能出在其中一个构造函数中。尝试拆分那条巨大的线路,并放入一些打印语句以查看问题所在。

    printf("Creating the first interval...\n");
    Interval a(x_mid, x_end);
    printf("Creating the second interval...\n");
    Interval b(y_mid-y_halfwidth, y_mid + y_halfwidth);
    printf("Creating the box...\n");
    Box* box_to_enqueue = new Box(gen_id, a, b);
    printf("Enqueueing the box...\n");
    // Do you really want to enqueue a pointer instead of a Box?
    queue->push_back(box_to_enqueue);
    

    【讨论】:

    • 并且不要忘记在这个序列中放置一个 fflush() ,否则错误消息可能最终会出现在未写入的缓冲区中。更好的是,使用调试器。
    猜你喜欢
    • 2015-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 2017-08-05
    相关资源
    最近更新 更多