char *GetMemory( void ) { char p[] = "hello world"; return p; } void main( void ) { char *str = NULL; str = GetMemory(); printf( str ); }这个 GetMemory试图返回一个字符串。我的理解是,GetMemory函数创建了字符串p,其实p存放的是字符串的头地址,这个地址指向"hello world"的存放位置。但是函数结束的时候,p变量中存放的指向hello world的地址的内容被释放掉了,然后p中的那个地址就编程没有指向内容,内存泄漏?然后报错?是吗?
我来解释下你的问题,可能会有点长
charp[]="helloworld"; -称为A定义方式
char*p="helloworld"; -称为B定义方式
两个p的区别
分两种情况:
1
这个p是全局变量(通俗点就是在函数外面定义的)
那么这两种方式,产生的效果有点相同的地方:
A:使用A定义方式,只分配了 sizeof(p)== sizeof("helloworld")==12字节的内存
(字符串长度为11,加上一个字节的结束符号)
p是这段内存的开始地址,他不是实际的指针变量,所以 p=p+1; 这类的操作,连编译都通过不了。
B:使用B定义方式,字符串分配了sizeof("helloworld")==12
的内存,除了这之外还分配了sizeof(p)==sizeof(void*)的内存(一个指针的内存一般是4或8字节)
p是一个指针,它存的值是这个字符串的开始地址。所以 p++;p="shit"; 这类的操作都是合法的。
但是如果B方式没有修改p指针的指向,这两种方式使用p都能够获取到字符串"helloworld",产生是一样的错觉,其实差别很大。
但是有一点是相同的: 相同的字符串"helloworld"会存放在全局变量存放的地方。
2
这个p是局部变量(通俗点就是在函数内部定义的)
那么这两种方式,产生的效果就会有很大的不同:
A:使用A定义方式,只在stack(栈)中分配了12字节的内存
p是这段内存的开始地址,他不是实际的指针变量,所以 p=p+1; 这类的操作,连编译都通过不了。
而且只能在函数内部使用p,函数返回后,p这块内存值就是非法的了
B:使用B定义方式,也是在全局变量区分配了sizeof("helloworld")==12的内存,
除了这之外还在stack(栈)中分配了一个指针的内存
p是一个指针,它存的值是这个字符串的开始地址。所以 p++;p="shit"; 这类的操作都是合法的。
但是只能在函数内部使用p
还有一个可以修改和不能修改忘记说了回答的不能再好了不是内存泄露,当函数调用的时候,里面你只是用到了局部变量,自然函数调用完之后就被自动清除了,所以指针指向的地方已经没有数据了,不存在内存泄露;如果你在函数中换成malloc就可以成功返回了,不过记得自己用完后释放,否则会造成内存泄露回复 @幻の上帝:你看下我回复zerodeng的错。此处决定生存期的重点是存储类而不是作用域。自动局部对象会在块结束时销毁,但静态局部对象就不会。大概对吧回复 @Xsank:“HelloWorld”这个数据还在,会被编译器放到.rodata这个只读的段里回复 @txgcwm:多半会被覆盖,栈空间那么少如果那块内存被其他数据覆盖了,就出问题了用char*p="abc";就可以了要加const
printf(str);
=》楼主这样也不合理,要么就用puts(str);
“Youshouldnever returnanaddresstoalocalvariable”版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。