2017-01-04 3 views
0

Я не программист C, но недавно проявил к нему интерес. Я пытаюсь изменить узел файла YAML, используя библиотеку C libyaml. Когда я пытаюсь изменить узел из скалярных данных события, компилятор не жалуется, но я получаю ошибки ошибки сегментации.Как изменить существующий узел YAML в C?

while (!done) 
{ 
    /* Get the next token. */ 

    if (!yaml_parser_parse(&parser, &event)) 
     goto parser_error; 

    //yaml_parser_scan(&parser, &token); 

    /* Check if this is the stream end. */ 

    if(beginServerNodes && event.type == 8) { 
     beginServerNodes = 0; 
    } 

    if (event.type == YAML_SCALAR_EVENT) { 
     if(beginServerNodes == 1) { 
     //I WANT TO MODIFY THIS VALUE 
     printf("%s\n", event.data.scalar.value); 
     } 
     if(strcmp("servers",event.data.scalar.value) == 0) { 
     beginServerNodes = 1; 
     } 
    } 

    if (event.type == YAML_STREAM_END_EVENT) { 
     done = 1; 
    } 
    /* Emit the token. */ 

    if (!yaml_emitter_emit(&emitter, &event)) 
     goto emitter_error; 
} 

Таким образом, хотя в этом цикле, когда я пытаюсь изменить следующее значение

event.data.scalar.value 

Оно должно быть типа yaml_char_t

yaml_char_t *newHost = "10.132.16.48:6379:1 redis-001"; 
    event.data.scalar.value = newHost; 
    event.data.scalar.length = sizeof(newHost); 

Компилятор не жалуется, и код запуска путем штампов с дефектом сегрегации. Если вы видели примеры в тестовых каталогах libyaml, но ничего не интуитивно понятное, просто редактирование узла, по крайней мере, не для C newb, как я.

+0

OK, одно замечанием, что я могу сделать, не смотря на актуальный вопрос: с помощью 'goto' неодобрение большинства программистов, и, конечно, не то, что вы должны быть используя, когда только начинаешь с C. Он имеет некоторые [лигитивные варианты использования] (http://stackoverflow.com/questions/245742/examples-of-good-gotos-in-c-or-c), но при обучении C лучше избегать его, а не делать его частью обычного повседневного рабочего процесса. –

+0

Это не так, потому что «goto» так сложно использовать, но использование его, как и любой другой инструкции по управлению потоком **, приведет к некоторому чрезвычайно трудному обнаружению ошибок, которые уберут большую часть вашего времени и большую часть удовольствия от обучения C. Прочитайте [этот классический] (http://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf) Э.Дейкстра. –

+0

@RodyOldenhuis Я бы согласился с вами, что использование этой конструкции goto было взято непосредственно из примера в самой библиотеке. –

ответ

1

Libyaml ожидает, что значения каждого скаляра можно удалить с помощью free(). Таким образом, вы должны инициализировать это значение с malloc() эдов памятью:

const char* newHost = "10.132.16.48:6379:1 redis-001"; 
event.data.scalar.value = (yaml_char_t*)strdup(newHost); 
event.data.scalar.length = strlen(newHost); 
Смежные вопросы