调用结构的虚函数时出现segfault

seg fault when calling virtual function of struct

本文关键字:segfault 函数 结构 调用      更新时间:2023-10-16

下面是一个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关键字时,代码运行良好。有人能帮我解释一下原因吗?

calloc()只能用于为基本类型和POD结构分配空间。因为你的结构有一个虚函数,它不是POD,所以你需要使用new来确保虚函数表被正确创建。

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的内存分配函数。