Char* 在函数中使用 malloc 创建,编译器说地址在堆栈上,无法返回

Posted

技术标签:

【中文标题】Char* 在函数中使用 malloc 创建,编译器说地址在堆栈上,无法返回【英文标题】:Char* created using malloc in function, compiler says address is on the stack and cannot be returned 【发布时间】:2019-05-16 08:02:51 【问题描述】:

我正在编写一个函数,它应该将字符串作为输入并在单词周围添加引号,然后返回指向新修改字符串的指针。

//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] 返回 (&word_quotes); ^~~~~~~~~~~~~~

【问题讨论】:

顺便说一句,你听说过strlen()strcpy()吗? 【参考方案1】:
char f() 
    char a = 'a';
    return &a;

变量a 在函数返回后停止存在。所以函数返回后,变量a不存在,函数返回后变量&amp;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;

【讨论】:

我编辑了我的帖子以显示我如何处理返回的值。我认为这意味着我需要返回一个 char** 并且我将无法动态返回一个字符串。你还认为我应该只返回一个 char* 吗? 你可以返回一个char**,但是你必须为它分配内存。喜欢char **ret = malloc(sizeof(*ret)); *ret = word_quotes; return ret;。拿一张纸,试着画出指针指向的地方。 word_quotes 已经是指向字符串的指针,返回指向字符串指针的指针是没有意义的。此外,您的新代码(非常)无效,*new_word_w_qs[m]; 被分组为*(new_word_w_qs[m]); - 所以首先new_word_w_qs 增加m 并取消引用然后取消引用。你要(*new_word_w_qs)[m]先获取双指针的值,再获取m字符 为什么是 calloc 而不是 malloc? 只是想避免在调用strcat之前输入word_quotes[0] = '\0'。但是,我可以在第一个代码片段中使用mallocstrcpy(word_quotes, "\"");。在第二个中,它没有任何区别。我想这只是我使用字符串时的一种习惯。 sprintf 是否在末尾添加 '\0'?我有单词长度 + 3,因为我添加了 '\0' 但你没有。

以上是关于Char* 在函数中使用 malloc 创建,编译器说地址在堆栈上,无法返回的主要内容,如果未能解决你的问题,请参考以下文章

了解何时需要 malloc():我在编译时知道 char * n 的长度,但似乎仍然需要 malloc()

malloc在函数内分配内存问题

C语言 malloc()函数 分配内存空间尺寸的问题

C语言 malloc()函数 分配内存空间尺寸的问题

入职培训笔记记录--day9(1指针函数与函数指针函数指针数组 2malloc memset 3递归函数 4结构体 5共用体---》大小端 6枚举)

函数内的指针变量指向堆栈还是堆?