2016-08-12 72 views
0

的虚函数时,我有一个C++代码,低于该创建指针数组一个struct赛格故障主叫结构

#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; 
} 

我认为该构建体是正确的,但它在线路

给出了SEG故障错误
WATCH(mat1->getDensity()) 

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

+2

在C++程序中停止使用'C'构造,如'calloc'。另外,'typedef struct'是来自'C'代码的保留。我认为你需要阅读C++的材料,并把'C'的东西拿走。 – PaulMcKenzie

回答

2

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

+0

这是有效的。现在我知道一个包含虚拟结构的结构需要使用新的mem分配 – kstn

+0

@kstn在C++中,您应该始终使用'new','malloc()'是C. – Barmar