Hel*_*rld 24 c return strcpy strcat
我是C的初学者,我正在自学.我正在创建以下功能:
char *foo(int x){
if(x < 0){
char a[1000];
char b = "blah";
x = x - 1;
char *c = foo(x);
strcpy(a, b);
strcat(a, c);
return a;
}
blah ...
}
Run Code Online (Sandbox Code Playgroud)
我基本上试图返回一个附加的字符串,但我收到以下错误:
"错误:函数返回局部变量的地址",任何建议,如何解决这个问题?
pho*_*xis 43
局部变量的生命周期仅在定义它的块内部延伸.当控件超出定义局部变量的块之外时,不再分配(不保证)变量的存储.因此,使用变量的生命周期区域外的变量的内存地址将是未定义的行为.
另一方面,您可以执行以下操作.
char *str_to_ret = malloc (sizeof (char) * required_size);
.
.
.
return str_to_ret;
Run Code Online (Sandbox Code Playgroud)
并使用str_to_ret相反.当returning时str_to_ret,malloc将返回分配的地址.分配的内存malloc是从堆中分配的,其堆的生命周期跨越程序的整个执行.因此,您可以在程序运行时随时随地访问内存位置.
另请注意,在完成分配的内存块之后,这是一个很好的做法,free它可以避免内存泄漏.释放内存后,无法再次访问该块.
我想出了这个简单直接(我希望如此)的代码示例,它应该解释自己!
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* function header definitions */
char* getString(); //<- with malloc (good practice)
char * getStringNoMalloc(); //<- without malloc (fails! don't do this!)
void getStringCallByRef(char* reference); //<- callbyref (good practice)
/* the main */
int main(int argc, char*argv[]) {
//######### calling with malloc
char * a = getString();
printf("MALLOC ### a = %s \n", a);
free(a);
//######### calling without malloc
char * b = getStringNoMalloc();
printf("NO MALLOC ### b = %s \n", b); //this doesnt work, question to yourself: WHY?
//HINT: the warning says that a local reference is returned. ??!
//NO free here!
//######### call-by-reference
char c[100];
getStringCallByRef(c);
printf("CALLBYREF ### c = %s \n", c);
return 0;
}
//WITH malloc
char* getString() {
char * string;
string = malloc(sizeof(char)*100);
strcat(string, "bla");
strcat(string, "/");
strcat(string, "blub");
printf("string : '%s'\n", string);
return string;
}
//WITHOUT malloc (watch how it does not work this time)
char* getStringNoMalloc() {
char string[100] = {};
strcat(string, "bla");
strcat(string, "/");
strcat(string, "blub");
//INSIDE this function "string" is OK
printf("string : '%s'\n", string);
return string; //but after returning.. it is NULL? :)
}
// ..and the call-by-reference way to do it (prefered)
void getStringCallByRef(char* reference) {
strcat(reference, "bla");
strcat(reference, "/");
strcat(reference, "blub");
//INSIDE this function "string" is OK
printf("string : '%s'\n", reference);
//OUTSIDE it is also OK because we hand over a reference defined in MAIN
// and not defined in this scope (local), which is destroyed after the function finished
}
Run Code Online (Sandbox Code Playgroud)
编译时,您会得到[预期]警告:
me@box:~$ gcc -o example.o example.c
example.c: In function ‘getStringNoMalloc’:
example.c:58:16: warning: function returns address of local variable [-Wreturn-local-addr]
return string; //but after returning.. it is NULL? :)
^~~~~~
Run Code Online (Sandbox Code Playgroud)
......基本上我们在这里讨论的是什么!
运行我的示例产生此输出:
me@box:~$ ./example.o
string : 'bla/blub'
MALLOC ### a = bla/blub
string : 'bla/blub'
NO MALLOC ### b = (null)
string : 'bla/blub'
CALLBYREF ### c = bla/blub
Run Code Online (Sandbox Code Playgroud)
理论:
用户@phoxis已经很好地回答了这个问题.基本上这样考虑一下:{和}之间的所有东西都是局部范围,因此C-Standard在外面是"未定义的".通过使用malloc,您可以从HEAP(程序范围)获取内存,而不是从STACK(函数范围)获取内存- 因此它从外部"可见".第二种正确的方法是按引用调用.在这里定义父范围内的var,因此它使用STACK(因为父范围是main()).
摘要:
3种方法,其中一种是假的.C是一种笨拙的函数,只需要一个函数返回一个动态大小的字符串.您必须使用malloc然后释放它,或者您必须按引用调用.或者使用C++;)
不需要malloc或通过引用调用。您可以在函数内声明一个指针,并将其设置为您要返回的字符串/数组。
使用@Gewure的代码作为基础:
char *getStringNoMalloc(void){
char string[100] = {};
char *s_ptr = string;
strcat(string, "bla");
strcat(string, "/");
strcat(string, "blub");
//INSIDE this function "string" is OK
printf("string : '%s'\n", string);
return s_ptr;
}
Run Code Online (Sandbox Code Playgroud)
完美地工作。
在原始问题中使用代码的非循环版本:
char *foo(int x){
char a[1000];
char *a_ptr = a;
char *b = "blah";
strcpy(a, b);
return a_ptr;
}
Run Code Online (Sandbox Code Playgroud)
a是在函数内部定义的,不能在函数外部使用。如果你想char从函数返回一个数组,你需要动态分配它:
char *a = malloc(1000);
Run Code Online (Sandbox Code Playgroud)
并在某个时刻调用free返回的指针。
您还应该在这一行看到警告::char b = "blah";您正在尝试将字符串文字分配给char.
| 归档时间: |
|
| 查看次数: |
82835 次 |
| 最近记录: |