首页 > c/c++, 面试 > linux c 堆变量,栈变量,指针参数,非指针参数剖析

linux c 堆变量,栈变量,指针参数,非指针参数剖析

2015年12月7日 685 人阅读 发表评论 阅读评论

1、概念

2.1 堆:程序可以动态申请的存储空间,通过malloc系列函数分配,全局可访问。

2.2 栈:程序在进行函数调用时动态伸缩的存储空间,局限于函数内可以访问。

2.3 堆变量:数据存储在堆的变量,全局可访问。

2.4 栈变量:函数中声明的局部变量,只能在函数内部访问,否则访问行为的结果是未定义的。

2.5 指针参数:参数类型为指针的参数。

2.6 非指针参数:参数类型不是指针的参数。

2、问题剖析

2.1 如何正确的分配内存?

先看下面的代码:

void * fun_m1()

{

char buf[100];

return (void *)buf;

}

void * fun_m2(size_t size)

{

return malloc(size);

}

void fun_m3(size_t size, void * p)

{

p = malloc(size);

}

void fun_m4(size_t size, void ** p)

{

*p = malloc(size);

}

fun_m1是错误的,因为它返回的栈变量的地址,如果对它访问的地址进行读写,程序行为的结果是未定义的。

fun_m2是正确的,因为它返回的是malloc申请的堆空间的地址。

fun_m3和fum_m4很具有迷惑性,要分区fun_m3和fun_m4的区别,我们这里需要澄清一个概念:任何的参数传递本质上都是值拷贝,任何参数都是栈变量在我们以往观念中参数传递就是两种:值传递,指针传递,而通过指针可以改变指针指向的变量;为什么说参数传递都是值拷贝呢,这是因为不管参数是否为指针,传递的都是一份值的拷贝,只不过当你的参数类型为指针时,你传递的是指针变量的值,而通过*操作符作用在指针变量上,你又刚好可以影响到指针变量关联的其他变量的值。

通过上面的剖析我们可以知道fun_m3是错误的,因为没有*操作符作用在p上,单纯对p赋值操作只会影响到局部的栈变量p的值,而不会对函数fun_m3外的变量有任何影响。fun_m4是正确的,因为有*操作符作用在p上,通过对*p赋值来修改传递给p的参数,使它指向申请的堆空间。

2.2 如何判断堆和栈的“增长”方向(从低到高,还是从高到低)

2.2.1 栈的“增长”方向

void fun1()

{

int a;

printf(“%p\n”, &a);

}

void fun2()

{

int b;

printf(“%p\n”, &b);

fun1();

}

通过比较a和b的地址大小,就可以判断出栈的“增长”方向,b地址大于a地址对应的是“从高到低”,反之对应的是“从低到高”。

2.2.2 堆的“增长”方向

void fun()

{

void * a = sbrk(10);
void * b = sbrk(20);
printf(“a=%p,b=%p\n”, a, b);

}

通过比较a和b的地址大小,就可以判断出栈的“增长”方向,b地址大于a地址对应的是“从高到低”,反之对应的是“从低到高”。

 

分类: c/c++, 面试 标签:
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.