【C++内存管理】浅析C++中函数调用时的内存分配-函数局部变量的内存分配

学习了C++这么久,内存问题感觉一直是一个拦路虎一样,说懂了感觉懵懵懂懂,说没懂吧,感觉也不是啥都不知道。有必要把它整理出来作为自己的一个知识体系的架构吧。

现在就从函数调用时的内存管理入手。

一、函数中普通变量的内存分配问题

我们知道当一个函数进行调用时,函数的形参、以及函数的局部变量都会在栈中被分配内存,而栈又可分为两种,一种是栈底不变,栈顶不断的动态变化;另一种是栈顶不变,栈底在动态变化。那么我们平常使用的栈属于那种呢?函数的局部变量在分配地址时是从高到低还是从低到高呢?带着这两个问题,我们做以下试验:

#include<iostream>
using namespace std;
void print()
{
	int a=0;
	int b=1;
	int c=2;
	cout<<"&a="<<reinterpret_cast<void*>(&a)<<endl;
	cout<<"&b="<<reinterpret_cast<void*>(&b)<<endl;
	cout<<"&c="<<reinterpret_cast<void*>(&c)<<endl;
}
int main()
{
	print();
	return 0;
}

从代码中可以看出我们在函数print中定义了三个局部变量,分别打印这三个局部变量的地址值,只要比较地址值得高低,我们需要验证的上面两个问题就有了结论。

结果如下:

[Hyman@Hyman-PC cplus]$ g++ array.cpp 
[Hyman@Hyman-PC cplus]$ ./a.out 
&a=0xbffc467c
&b=0xbffc4678
&c=0xbffc4674

可以发现,abc地址依次降低,所以我们有了结论,在C++函数调用的过程中定义的局部变量是采用栈顶不变,栈底不断变化的内存栈,随着声明顺序,内存地址依次降低。

 

二、函数中数组变量的内存分配问题

在函数的局部变量中,还有一种特殊的类型,就是数组,关于数组的定义有以下疑问:

1、数组在分别时是一次性分配整个数组的内存?

2、数组中各个元素的地址分配顺序是怎么样的?

带着上面的疑问,我们继续验证:

#include<iostream>
using namespace std;
void print()
{
	int a=0;
	int b=1;
	int c=2;
	int arr[2];
	cout<<"&a="<<reinterpret_cast<void*>(&a)<<endl;
	cout<<"&b="<<reinterpret_cast<void*>(&b)<<endl;
	cout<<"&c="<<reinterpret_cast<void*>(&c)<<endl;
	cout<<"&arr[0]="<<reinterpret_cast<void*>(arr)<<endl;
	cout<<"&arr[1]="<<reinterpret_cast<void*>(&arr[1])<<endl;
}
int main()
{
	print();
	return 0;
}

上面的代码中,我们又定义了一个数组,分别打印数组中元素的地址信息:

<pre name="code" class="plain">[Hyman@Hyman-PC cplus]$ g++ array.cpp 
[Hyman@Hyman-PC cplus]$ ./a.out 
&a=0xbff1646c
&b=0xbff16468
&c=0xbff16464
&arr[0]=0xbff1645c
&arr[1]=0xbff16460


 

从地址打印的情况来看,很明显函数中一次性为数组分配了整个数组需要的内存,然后数组中各个元素排序是从低到高一次排列的,也就是说先放arr[0]到低地址位置,然后放arr[1]到高地址位置。

整个实验过程中内存的分配图如下:

三、一个有趣的试验

#include<iostream>
using namespace std;
void print()
{
	cout<<"hello world"<<endl;
}

void test()
{
	int arr[1];
	arr[2]=(int)print;
}

int main()
{
	test();
	return 0;
}

先看,以上代码,运行结果为:

[Hyman@Hyman-PC cplus]$ g++ array.cpp 
[Hyman@Hyman-PC cplus]$ ./a.out 
hello world

问题:为什么上述代码中根本没有调用print函数的语句,但是却打印出来了hello world的?


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值