значение массива не обновляется - PullRequest
0 голосов
/ 10 мая 2018

У меня есть реализация strtok (вроде), но она не печатает токен!

char *tokenizer(char s[], const char *delimiter) {
     char *p;                   //return value of function
     int i = 0;
     while(s[i] != *delimiter)  //to get the size of array just right
         i++;

     char arr[i+1];
     p = arr;                  //can't return an array, so assigned to a
                               //pointer       
     int j = 0;
     i = 0;
     while(s[i]!=*delimiter) {
           arr[j] = s[i];
           i++;
           j++;
     }
     arr[j] = '\0';     
     printf("%s\n",p);         //this statement works, but if excluded
                               //main prints nothing.
     return p;
}

Эта функция вызывается из основного списка следующим образом:

char s[] = "tab-tab";
const char del[2] = "-";
char *p;
p = tokenizer(s, del);
printf("%s\n", p);        //prints nothing without the printf in
                          //tokenizer

Я попытался отладить с помощью gdb и проверял значения локальной переменной после каждой строки. p обновляется с arr[j] внутри tokenizer, но становится равным нулю, как только tokenizer заканчивается и кадр возвращается к main.

Значение p в main не становится NULL, оно становится пустой строкой и печатает это!

Однако p в main печатает токен, если включено printf в tokenizer.

Это уже включает обходной путь. Я знаю, что это не может быть способом реализации strtok. Я начал с более сложной, «опытной» версии, которая имела указатели, но не могла заставить ее работать, поэтому согласился на эту версию «для начинающих».

1 Ответ

0 голосов
/ 10 мая 2018

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

char *tokenizer(char s[], const char *delimiter) {
    char *arr;

    int i = 0;
    while(s[i] != *delimiter)
        i++;
    // Initialize variable in the heap
    if (!(arr = malloc(sizeof(char *) * (i+1))))
        return NULL;
    // Clear the array
    bzero(arr, (i+1));      
    int j = 0;
    i = 0;
    while(s[i]!=*delimiter) {
        arr[j] = s[i];
        i++;
        j++;
    }
    arr[j] = '\0';
    // return pointer
    return arr;
}

Необходимо обязательно освободить память в главном, чтобы предотвратить утечки памяти.

...