2014-02-13 6 views
2

Я получаю ошибку времени компиляции во время инициализации структуры членов в этом коде. Каковы могут быть некоторые другие методы для инициализации структуры ниже указанного массива. Спасибо!Инициализация структуры в C, лучшая практика

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

#define MAX_FUNC_MEMBERS 100 
#define MAX_FUNC_DESC_STR 50 

typedef struct member_struct { 
    double degree; 
    double coefficient; 
} member; 

typedef struct function_struct{ 
    member members[MAX_FUNC_MEMBERS]; 
    char *description; 
} *function; 

function malloc_function() { 
    return (function) malloc(sizeof(struct function_struct)); 
} 

double compute_function(function f, double x) { 
    return 0.0; 
} 

int main(void) { 
    // f1 = x^2 
    function f; 
    f->members = { 
     [0] = {2.0, 1.0}, 
     [1] = {1.0, 1.0} 
    }; 
    f->description = "x squared"; 

    return 0; 
} 
+0

Я подозреваю, что инициализация 'f-> членов. – Jeyaram

+0

Что лучше всего подходит для этого очень субъективно. Лично я бы никогда не использовал назначенные инициализаторы для массивов, потому что ... это не имеет большого смысла для этого.Если у вас есть массив, в котором вам нужно рассматривать каждый член массива как особый случай по любой причине, вы должны добавлять комментарии к каждой строке. – Lundin

ответ

0

У вас есть char * но вы не выделили память для строки она будет указывать на.

Вы могли бы сделать что-то вроде:

function f = malloc(sizeof(function)); 
const char *desc = "x squared"; 
f->description = malloc(strlen(desc) + 1); 
strcpy(f->description, desc); 

Чтобы убедиться, что он работает:

fprintf(stderr, "description: %s\n", f->description); 
+0

На самом деле это не его проблема, так как он не делает 'strcpy'. Не должно быть никаких проблем с простое назначение ему статического строкового литерала. – Dolda2000

2

В вашем конкретном случае, ваша программа также сегментации даже если он составлен, однако, так как вы» повторно назначая данные *f без его выделения.

Для вас есть несколько решений. Наиболее простым было бы, вероятно, просто выделить структуру function в стеке, но для этого потребуется либо изменить его typedef, либо не указывать указатель, либо напрямую использовать имя структуры. Я пойду с позже для этого примера:

struct function_struct fbuf = { 
    .members = { 
     [0] = {2.0, 1.0}, 
     [1] = {1.0, 1.0} 
    }, 
    .description = "x squared", 
}; 
function f = &fbuf; 

Еще бы инициализировать элементы один на один, вручную:

f = malloc(sizeof(*f)): 
f->members[0].degree = 2.0; 
f->members[0].coefficient = 1.0; 
f->members[0].degree = 1.0; 
f->members[0].coefficient = 1.0; 
f->description = "x squared"; 

Третий может быть использовать соединение буквального:

f = &(struct function_struct) { 
    .members = { 
     [0] = {2.0, 1.0}, 
     [1] = {1.0, 1.0}, 
    }, 
    .description = "apa", 
}; 

Это последнее сделано почти так же, как и первое, только является анонимным.

Вы также можете объединить второй и третий, если вы хотите, чтобы память о структуры, которые будут выделены в куче, а не на стеке:

f = malloc(sizeof(*f)): 
*f = (struct function_struct) { 
    .members = { 
     [0] = {2.0, 1.0}, 
     [1] = {1.0, 1.0}, 
    }, 
    .description = "apa", 
}; 

Что касается вашего «наилучшей практики» аспект, Я не думаю, что либо изначально лучше или хуже, чем любое другие, но они отличаются в некоторых аспектах:

  • третьи и четвертые, используя составные литералы, требуют ПОСЛЕДНЕЙ версии C, так что если вы» чтобы быть совместимыми с древними компиляторами C, они это плохая идея. Однако это должно быть редким вопросом в наши дни.
  • Первые и третьи выделяют данные в стеке, а второй и четвертый выделяют данные в куче. Это отличается, а не лучше или хуже, поэтому выбирайте то, что подходит вашему сценарию.
  • В зависимости от компилятора, второй пример может быть быть быстрее, так как он не касается 98 членов, которые остались неиспользованными. Однако вы должны были бы инициализировать много структур function в очень узком цикле, чтобы это было проблемой. :)
+0

Ну, еще одна вещь, которую я хотел знать о том, работает ли этот тип инициализации с ANSI C. –

+1

Это зависит от того, какой ANSI C. Третий и четвертый примеры не будут работать с ANSI C89, но это уже древняя история. Ни у одного из них не должно быть проблем с ANSI C99 или ANSI C11. – Dolda2000

+0

А также какая ошибка в объявлении f-> members я сделал. Я продолжаю получать ошибку даже после выделения пространства для объявления функции. –

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