2017-01-22 5 views
0

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

╠ a 

Вместо ожидаемый:

int 

У меня нет большой опыт работы на C, но я думаю, что это проблема с пустым завершением, хотя я читал, что strtok должен автоматически это делать.

Ниже приведен соответствующий код:

int tokenize(char* script, char* tokens[]) { 
    char buffer[256]; 
    strcpy(buffer, script); 

    char* token = strtok(buffer, " "); 
    int i = 0; 
    while (token) { 
     tokens[i] = token; 
     printf("token: %s\n", token); 
     token = strtok(NULL, " "); 
     i++; 
    } 
    printf("First token (tokenize): %s\n", tokens[0]); 

    return i; 
} 


int main(int argc, char* argv[]) { 
    // .... 
    char* script = read_script(argv[1]); 

    char* tokens[256]; 
    int token_count = tokenize(script, tokens); 
    printf("First token (main): %s\n", tokens[0]); 
    // ... 
} 

А вот вывод на консоль:

token: int 
token: i 
token: = 
token: 0 

First token (tokenize): int 
First token (main): ╠ a 

ответ

2

Вы возвращаются указатели, которые указывают на маркеры в локальной переменной:

int tokenize(char* script, char* tokens[]) { 
    char buffer[256]; 
    ... 

buffer больше не существует один раз tokenize() возвращение денег.

+1

И вопрос, который, вероятно, позволил бы ОП понять это для себя: кто или что выделил пространство указатели указывают и кто или что несет ответственность за их освобождение? –

1

Ваши strtok -calls действуют на локальную переменную buffer[256], а память, зарезервированная для этой переменной, больше не действует, как только tokenize возвращается. Следовательно, любой указатель в tokens[] укажет на (недопустимую) память.

Чтобы преодолеть это, я написал бы

tokens[i] = strdup(token); 

intstead из

tokens[i] = token; 

Убедитесь, что абонент освобождает память, таким образом, зарезервированную для каждого token[i] элемента, когда эти элементы не нужны Больше.

0

Объем памяти (буфер), указанный указателями, находится в стеке. Таким образом, это пространство исчезает, когда функция «tokenize» заканчивается. Итак, вы, переменная «токенов», должны указывать область кучи. (Используя malloc или calloc.)

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