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
不存在,函数返回后变量&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'
。但是,我可以在第一个代码片段中使用malloc
和strcpy(word_quotes, "\"");
。在第二个中,它没有任何区别。我想这只是我使用字符串时的一种习惯。
sprintf 是否在末尾添加 '\0'?我有单词长度 + 3,因为我添加了 '\0' 但你没有。以上是关于Char* 在函数中使用 malloc 创建,编译器说地址在堆栈上,无法返回的主要内容,如果未能解决你的问题,请参考以下文章
了解何时需要 malloc():我在编译时知道 char * n 的长度,但似乎仍然需要 malloc()
入职培训笔记记录--day9(1指针函数与函数指针函数指针数组 2malloc memset 3递归函数 4结构体 5共用体---》大小端 6枚举)