我初学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 ...
}
我基本上是试图返回一个字符串追加,但我得到了以下错误:
“错误:函数返回局部变量的地址”,有什么建议,如何解决这一问题?
局部变量具有仅延伸在其所定义的块内的生存期。 控制前进了其中本地变量被定义块以外的时刻,该变量的存储是没有更多的分配(不保证)。 因此,使用该变量的存储器地址的变量的生存区域之外将是不确定的行为。
在另一方面,你可以做到以下几点。
char *str_to_ret = malloc (sizeof (char) * required_size);
.
.
.
return str_to_ret;
并使用str_to_ret
代替。 当return
荷兰国际集团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
}
当编译它,您将获得[意]警告:
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? :)
^~~~~~
......基本上我们在这里讨论!
运行我的例子中得到的输出:
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
理论:
这已被用户@phoxis回答得很好听。 基本上,想想这样说:其间的一切{和}是局部范围内,从而由C-标准是“不确定”之外。 通过使用malloc你从HEAP(PROGRAMM范围)内存,而不是从堆栈 (函数范围) -因此,其从外部“可见的”。 做第二个正确的方法是调用-参考 。 在这里,您定义父范围内的变种,因此它被使用堆栈(因为父范围是在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;
}
完美的作品。
随着原题的代码的非循环的版本:
char *foo(int x){
char a[1000];
char *a_ptr = a;
char *b = "blah";
strcpy(a, b);
return a_ptr;
}
这条线:
char b = "blah";
没有好 - 你的左值必须是一个指针。
您的代码也是一个堆栈溢出的危险,因为你的递归检查没有边界x的减少值。
无论如何,你所得到的是实际的错误信息是因为char a
是一个自动变量; 此刻你return
将不复存在。 你需要的不仅仅是一个自动变量以外的东西。
a
是本地函数返回它不存在了,因此你不应该返回一个局部变量的地址function.Once的数组。
换句话说寿命 a
是范围内( {
, }
功能的),如果你返回一个指向它你有什么是指针指向一些内存是无效的。 这样的变量也叫自动 variabels,因为他们的寿命自动管理,你不需要明确的管理。
既然你需要扩展变量后仍然保持功能的范围你,你需要分配在堆阵列并返回一个指向它。
char *a = malloc(1000);
这样,阵列a
驻留在内存中,直到您拨打一个free()
在同一个地址。
不要忘了这样做,或者你结束了内存泄漏。
a
在功能本地定义的,并且不能被所述功能之外使用。 如果你想返回一个char
从功能阵列,你需要动态分配它:
char *a = malloc(1000);
在某些时候拨打free
对返回的指针。
你也应该看到,在这条线警告: char b = "blah";
:你想分配字符串文本的char
。