user-0 提问: c语言  用指针传递函数返回值总是失败

回复:
user: user-1
content: 引用 4 楼 Slzde_sub的回复:[quote=引用 3 楼 adlay 的回复:] 返回局部变量的指针, 程序行为是未定义的. 数组 a 在 create 函数返回后内存已被回收, 可能用于存放其他的数据了.   。。。为什么我认为这程序就不该被编译成功，本身就是错误的返回类型[/quote] 两个问题都存在

user: user-2
content: 引用 43 楼 蓝鲸灵的回复:声明一个数组时,编译器将根据声明所指定的元素数量为数组保留内存空间,然后再创建数组名,它的值时一个常量,指向这段空间的起始位置。 数组名是符号地址常量，在编译时求值并存在编译器的符号表里面，其值就是个内存地址；所以可以认为程序没有给a分配空间，数组名只是代表了那个数组空间；与指针不一样，指针指向一块空间，同时指针本身也存储在某个空间；可以认为数组名存在在符号表里，符号表是编译器用的，我们管不到；a和&a值是一样的，本来对常量取地址是非法的，但是标准组织没有定对数组名取地址是非法还是合法，所以因编译器而异，VC是合法的。 http://m.blog.chinaunix.net/uid-10221131-id-350168.html   具体可以看这里

user: user-2
content: 声明一个数组时,编译器将根据声明所指定的元素数量为数组保留内存空间,然后再创建数组名,它的值时一个常量,指向这段空间的起始位置。 数组名是符号地址常量，在编译时求值并存在编译器的符号表里面，其值就是个内存地址；所以可以认为程序没有给a分配空间，数组名只是代表了那个数组空间；与指针不一样，指针指向一块空间，同时指针本身也存储在某个空间；可以认为数组名存在在符号表里，符号表是编译器用的，我们管不到；a和&a值是一样的，本来对常量取地址是非法的，但是标准组织没有定对数组名取地址是非法还是合法，所以因编译器而异，VC是合法的。

user: user-2
content: 为什么没人提到对于return &a，c++编译器报错是无法从int*[8]转换成int*呢

user: user-3
content: 函数内的局部变量返回以后函数栈会被回收，返回局部变量指针就会出现未定义行为。

user: user-4
content: 函数内部创建的堆变量最好不要返回，不然使用者可能不知道这是堆变量从而忘记delete

user: user-5
content: 局部变量离开作用域就失效了，返回的指针应该是无效的

user: user-6
content: #include<cstdlib> #include<cstdio> #include<cstring> int* create() { 	int* a = new int[8]; 	int b[8] = { 1, 2, 3, 5, 2, 3, 5, 6 }; 	memcpy(a, b, sizeof(b)); 	int i;  	for (i = 0; i < 8; i++) 	{ 		printf("%hd\n", a[i]); 	}  	return a;//返回得到的整型数组的指针。 }   int main() { 	int i; 	int* b; 	b = create();  	for (i = 0; i < 8; i++) 	{ 		printf("%hd\n", b[i]); 	}  	delete b; 	system("pause"); }

user: user-0
content: #include <stdio.h>  int *p; int a[8] = {1,2,3,5,2,3,5,6}; int *create() {                                 //  a[8] = {1,2,3,5,2,3,5,6}; //	a[0]=1;  	p=a;     return p;//返回得到的整型数组的指针  }   void main() { 	int i;  //	int b[8] = {1,2,3,5,2,3,5,6}; //	p=b; 	p = create();  	for(i = 0; i < 8; i++) 	{ 		printf("%d\n",*p); 		p++; 	} } 我是这样写的

user: user-7
content: a是一个int数组，它的类型是int*，&a是取a的地址，它的类型应该是int** 另外a数组是在栈上创建的，其作用域在create()函数内部，函数返回后数组所占用的内存会被释放 可以使用malloc()函数在堆上动态分配内存

user: user-4
content: void create(int *p) { *p＝num1; *(p+1)＝num2; … }

user: user-4
content: a本身就是个指针，指向a[0]，不需要return &a;，直接return a;。但你这个数组a是栈变量，在函数结束后会被清理，会导致错误，所以需要在参数中传一个指针，在函数中改变这个指针指向的值，返回void

user: user-8
content: 数组 a 在 create 函数返回后内存已被回收

user: user-9
content: 指针作为函数返回值，返回的是指向内容的地址。  栈上申请的内存（new方式，会在堆上申请内存，需要自己主动释放），在退出其作用域时，自动释放。  int array[3] = {1, 2, 3};   // 栈上内存，，退出作用域时，自动释放。  所以，函数返回的指针，所指向的内容（栈上），在退出函数（int *create()）时，已经释放了。 所以，指向的内存地址，是一块未知的、非法的内存地址（不知道是啥内容）。  额外： 1.  指针和数组（首地址），是两个概念，最好不要把指针当成数组来用。 2.  补一下，堆与栈的知识吧。

user: user-10
content: 引用 5 楼 weixin_40101242的回复:[quote=引用 3 楼 adlay 的回复:] 返回局部变量的指针, 程序行为是未定义的. 数组 a 在 create 函数返回后内存已被回收, 可能用于存放其他的数据了.  那这个应该怎么解决呢，网上好多都是这么写的[/quote] 数组定义为static

user: user-11
content: 引用 12 楼 Slzde_sub 的回复:但是事实上编译器会对这个返回进行报错，因为返回类型和函数类型不同 你用的什么编译器会报错? 试试把你的文件扩展名改成 .c, 而不是 .cpp . 用 C 语言的编译器来编译, 不是用 C++ 的编译器来编译. 毕竟这里是 C 语言区, 讨论的是 C 语言.    引用 13 楼 Slzde_sub 的回复:当然。  a  等价于  &a[0]  这个我是支持的   ，但是我不认为 &a 可以和 a 等价， 你可以打印 printf("%p", a) 和 printf("%p", &a) 来看他们的值是否是一样的就知道了. 一个数组只对应内存中一块连续的内存, 无论是 a, 还是 &a 都是这块内存的首地址, 没有多余的内存, 也就没有多余的内存地址的.  引用 14 楼 hjwang77 的回复:不是吧，如果&a 等价于 &a[0], 那如果数组a 的元素是int *, 那 *a 和 *a[0]岂不是也一样？二维数组和一维数组不是混乱了？  在 C 语言里面, 二维数组本身就和一位数组没什么区别, 也只是一块连续的内存而已, 把二维数组转换成 int*p 后, 二维数组都可以按照一维数组的方式访问:  p[y * width + x], 二维数组的 a[x][y] 访问方式不过是一个语法糖而已.   引用 15 楼 hjwang77 的回复:不考虑栈的问题，函数定义的是返回int *, 而函数实现返回的是int **,没有强制转换编译起码是个警告 把返回类型认为是 int** 就错的有点离谱了. 注意数组 a 直接表示了一块内存, 而不是 a 定义了一个指针, 这个指针来指向一块内存, 注意这个区别:    建议看一下 C专家编程 这本书, http://blog.adintr.com/43

user: user-12
content: 你返回的是数组a的地址，在主函数中得到的也是a函数的地址，但自定义函数creat结束后，会对数组a进行销毁，所以主函数得到了a的地址也没用，因为那个地址存放的数据已被销毁

user: user-13
content: 那个变量a是临时变量，函数返回的时候就被回收了，返回地址也没有意义。

user: user-14
content: a  等价于  &a[0]

user: user-15
content: a  等价于  &a[0]  这个我是支持的   ，但是我不认为 &a 可以和 a 等价