Char * создан с использованием malloc в функции, компилятор говорит, что адрес находится в стеке и не может быть возвращен - PullRequest
3 голосов
/ 16 мая 2019

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

//add quotes around a single word
char** _add_quotes(char* word){
        int char_count = 0;
        while(word[char_count] != '\0'){
                char_count++;
        }
        char* word_quotes = malloc((char_count+3) * sizeof(*word_quotes));
        word_quotes[0] = '\"';
        for(int i =0; i < char_count; i++){
                word_quotes[i+1] = word[i];
        }
        word_quotes[char_count+1] = '\"';
        word_quotes[char_count + 2] = '\0';
        return (&word_quotes);
}

Вот где она возвращает

char** new_word_w_qs = _add_quotes(new_word); //add quotes
//copy new word with quotes to the final string
for (int m = 0; m < word_len; m++){
new_string[string_index] = *new_word_w_qs[m];
string_index++;
}

Я ожидал, что он вернет адрес строки в куче, вместо этого я получил ошибку.предупреждение: адрес стековой памяти, связанной с локальной переменной word_quotes, возвращен [-Wreturn-stack-address] return (& word_quotes);^ ~~~~~~~~~~

1 Ответ

1 голос
/ 16 мая 2019
char f() {
    char a = 'a';
    return &a;
}

Переменная a перестает существовать после возврата из функции. Таким образом, после возврата функции переменная a не существует, адрес переменной &a недействителен после возврата функции, там нет памяти после возврата функции.

char **f2() {
   char *b = "abc";
   return &b;
}

Это то же самое. Переменная b не существует после функции, поэтому адрес переменной b недействителен после возврата функции. Неважно, если это указатель. Адрес, хранящийся в переменной b, все еще действителен, но адрес переменной b недействителен после возврата функции.

Просто возвращайте указатель по значению, а не указатель на указатель.

//add quotes around a single word
char* _add_quotes(char* word){
        ...
        char* word_quotes = malloc((char_count+3) * sizeof(*word_quotes));
        ...
        // this is the value as returned by malloc()
        // the pointer value returned by malloc still valid after the function returns 
        return word_quotes;
}

И ваша функция может быть переписана для использования стандартных библиотечных функций:

char* _add_quotes(char* word){
        char* word_quotes = calloc((strlen(word) + 3), sizeof(*word_quotes));
        if (word_quotes == NULL) return NULL;
        strcat(word_quotes, "\"");
        strcat(word_quotes, word);
        strcat(word_quotes, "\"");
        return word_quotes;
}

или даже:

char* _add_quotes(char* word){
        char* word_quotes = calloc((strlen(word) + 3), sizeof(*word_quotes));
        if (word_quotes == NULL) return NULL;
        sprintf(word_quotes, "\"%s\"", word);
        return word_quotes;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...