2015-10-10 3 views
0

Я работаю над проектом, целью которого является создание автоматов.realloc массив структуры внутри другой структуры

Автоматы определяются структуры:

typedef struct { 
    int num_states; 
    int initial_state; 
    State * states; 
} Automaton; 

И государство еще одна структура определения дуг между состояниями:

typedef struct { 
    int num_arcs; 
    bool is_final; 
    Arc * arcs; 
} State; 

typedef struct { 
    int symbol; 
    int destination; 
} Arc; 

создать автомат с таНос как таковой:

Automaton* create_automaton(void) { 
    Automaton * a = (Automaton *)malloc(sizeof(Automaton)); 
    assert(a != NULL); 
    a->initial_state = UNDEFINED; 
    a->num_states = 0; 
    a->states = NULL; 
    return a; 
} 

Итак, я хочу взять 2 автомата с состояниями и дугами, созданными с помощью этих функций:

int add_state(Automaton* a) { 
    State* state = (State *)realloc(a->states, (a->num_states + 1) * sizeof(State)); 
    if(state == NULL) 
     exit(EXIT_FAILURE); 
    a->states = state; 
    a->states[a->num_states].num_arcs = 0; 
    a->states[a->num_states].is_final = FALSE; 
    a->states[a->num_states].arcs = NULL; 

    return a->num_states++; 
} 

void add_arc(Automaton* a, int from, int to, int symbol) { 
    if(from >= a->num_states || to >= a->num_states) 
     exit(EXIT_FAILURE); 
    Arc * arc = (Arc *)realloc(a->states[from].arcs, (a->states[from].num_arcs + 1) * sizeof(Arc)); 
    if(arc == NULL) 
     exit(EXIT_FAILURE); 
    a->states[from].arcs = arc; 
    a->states[from].arcs[a->states[from].num_arcs].destination = to; 
    a->states[from].arcs[a->states[from].num_arcs].symbol = symbol; 
    a->states[from].num_arcs++; 
} 

Я хочу объединить эти 2 Автоматы в одном, так что я написал эту функцию:

Automaton* append_automaton(Automaton * a1, Automaton * a2) 
{ 
    Automaton * a = copy_automaton(a1); 
    int i = 0; 
    for(i = 0; i < a2->num_states; i++) 
    { 
     add_state(a); 
     a->states[a1->num_states + i] = a2->states[i]; 
     for(j = 0;j<a->states->num_arcs;j++) 
     { 
      a->states[i].arcs[j].destination =+ a2->num_states; 
     } 
    } 
    a->initial_state = a1->initial_state; 

    return a; 
} 

Однако я могу создать автоматных, добавлять состояния и дуги к нему без каких-либо проблем, когда я пытаюсь объединить их вместе с append_automaton. Я получаю ошибку сегментации, когда в add_state() я realloc State устанавливаю еще одно состояние в новом автомате.

Итак, мой вопрос заключается в следующем: почему realloc дает мне ошибку сегментации, когда в этой функции (append_automaton), хотя она отлично работает вне ее?

PS: copy_Automaton() действительно перезаписать create_Automaton(), так что я удалил строку: Automaton * a = create_automaton() в append_automaton() А вот copy_automaton():

Automaton* copy_automaton(Automaton* a) { 
    int i = 0; 
    Automaton * cp_a = malloc(sizeof(Automaton)); 
    cp_a->states = malloc(sizeof(a->states)); 
    for(i = 0; i < a->num_states; i++) 
    { 
     cp_a->states[i].arcs = malloc(sizeof(a->states[i].arcs)); 
     cp_a->states[i] = a->states[i]; 
    } 
    cp_a->num_states = a->num_states; 
    cp_a->initial_state = a->num_states; 
    //memcpy(a, cp_a, sizeof(Automaton)); 
    return cp_a; 
} 
+0

Можете ли вы предоставить минимальный пример нерабочего ввода, который segfault? Также вы сказали add_arc() segfault, но эта функция никогда не вызывается. –

+0

Извините, я имел в виду add_state() segfault not add_arc() –

+0

В append_automaton() присваивание 'a = copy_automaton (a1);' вытирает предыдущее значение 'a = create_automaton();' (инициализатор) – wildplasser

ответ

3

Проблема, которую я вижу в вашей обновлении a->num_states после цикла. Однако a->num_states используется внутри цикла в функции add_state(a); Вы должны поместить (a-> num_states) ++ внутри цикла.

+0

Да, спасибо, я не видел эту ошибку, но я все еще получаю отказ от realloc при добавлении государство. Проблема в том, что я обновляю a-> num_states в цикле for num_states на 2, потому что add_state также увеличивает num_state. Поэтому я просто удалил num_state incrementation в append_automaton. –