2016-08-12 2 views
0

У меня есть код 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 удалено, код работает нормально. Может ли кто-нибудь помочь мне объяснить, почему?

+2

Остановить использование 'C'-конструкций, таких как' calloc' в программе на C++. Кроме того, 'typedef struct' является задержкой с кодом' C'. Я думаю, вам нужно прочитать материал на C++ и выложить материал 'C'. – PaulMcKenzie

ответ

2

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.

+0

Это действительно. Теперь я знаю, что для структуры, содержащей виртуальную, нужно использовать новое для размещения mem – kstn

+0

@kstn В C++ вы должны просто использовать 'new' все время,' malloc() 'для C. – Barmar

Смежные вопросы