【问题标题】:seg fault when calling virtual function of struct调用结构的虚函数时出现段错误
【发布时间】:2016-08-12 20:46:53
【问题描述】:

我在下面有一个 C++ 代码,它创建了一个指向结构的指针数组

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

#define WATCH(x) std::cout << #x << ": " << x << std::endl;

typedef struct
{
    double  thickness;
    char    name[80];
    virtual double getDensity() const {return 0.1;}
} mat_prop_t;

struct mat_el_prop : public mat_prop_t
{
    double  density;
    double  young;
    double  poisson;
    virtual double getDensity() const {return density;}
};

int main(int argc, char** argv)
{
    mat_prop_t**            mat_prop;
    mat_prop = (mat_prop_t**) calloc(1, sizeof(mat_prop_t*));
    mat_prop[0] = (mat_prop_t*) calloc(1, sizeof(mat_el_prop));
    mat_el_prop* mat1 = (mat_el_prop*) mat_prop[0];
    mat1->density = 2.038735;
    mat1->young = 2.0;
    mat1->poisson = 0.3;
    mat1->thickness = 1.0;
    WATCH(mat1->density)
    WATCH(mat1->getDensity())

    free(mat_prop[0]);
    free(mat_prop);

    return 0;
}

我认为构造是正确的,但它在行给出了一个段错误错误

WATCH(mat1->getDensity())

但是,当virtual 关键字被删除时,代码运行良好。谁能帮我解释一下为什么?

【问题讨论】:

  • 停止在 C++ 程序中使用 C 结构,例如 calloc。此外,typedef structC 代码的保留。我认为您需要阅读 C++ 材料,并将 C 的东西收起来。

标签: c++ struct segmentation-fault


【解决方案1】:

calloc() 只能用于为原始类型和 POD 结构分配空间。由于你的struct有虚函数,不是POD,所以需要使用new来保证vtable的创建正确。

mat_prop_t **mat_prop = new mat_prop_t*[1];
mat_prop[0] = new mat_el_prop;
mat_el_prop *mat1 = mat_prop[0];

从技术上讲,您可以将calloc() 用于mat_prop,因为它是一个指针数组。但在 C++ 中,您通常应该使用new,而不是 C 内存分配函数。

【讨论】:

  • 这是有效的。现在我知道对于包含虚拟的结构需要使用 new 进行内存分配
  • @kstn 在 C++ 中,您应该一直使用 newmalloc() 用于 C。
猜你喜欢
  • 2020-04-04
  • 2020-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
相关资源
最近更新 更多