今天在碰到一个奇怪的问题,new是全新分配内存的吗?如果你的回答是是,那么编译运行下面的程序看看为什么int a[10];a=new int[20];之后原来数组a中的数据仍旧存在呢?如果你的答案是否,那么新new的内存是接在原a数组内存之后的吗或者原来的数据被自动拷贝到新的内存中来了?你的答案是什么呢?(使用gcc编译器编译,使用vc中的cl编译器编译可能需要简单的修改程序)
/****求能被7或11整除的数*******/
#include "iostream.h"
//using namespace std
const int increament=10;
int function(int m, int a[] )
{
int i,n=0,length=10;
int *ptr=a;
for (i=1;i<=m;i++)
{
if (!(i%7) || !(i%11))
{
if (n==length) //当n等于length时增加数组的长度
{
a=new int[length+increament];
ptr=&a[n-1];
length+=increament;
}
*ptr=i;
ptr++;
n++;
}
}
return n;
}
int main()
{
int i,m,n,a[10];
cout << "请输入m:";
cin >> m;
n=function(m,a);
for (i=0;i<n;i++) cout << a[i] << " ";
cout << endl << "n=" << n << endl;
cin>>m;
return 1;
}
这段程序是求从1到m中能被7或11整除的数,开始声明了整型数组a[10]用来存储内被7或11整除的数,如果能被7或11整除的数大于10那么加长数组a[]一倍,当m<49的时候也就是说数组a[]不被加长的时候,这个程序的所打印的数据是正常的,但当m>48的时候,数组加长之后,前10个数据是正确的但后面的就是错误的了。于是又有了开始的一连串的疑问。
为了搞清楚这些疑问我打印了程序中关键变量的地址如下:
/****求能被7或11整除的数*******/
#include "iostream.h"
//using namespace std
const int increament=10;
int function(int m, int a[] )
{
int i,n=0,length=10;
int *ptr=a;
cout<<"函数中a的地址:"<<a<<endl; //与原来的a的地址相同
for (i=1;i<=m;i++)
{
if (!(i%7) || !(i%11))
{
if (n==length)
{
a=new int[length+increament];
cout<<"new a地址:"<<a<<endl; //a的地址不同
cout<<"new a 之后a[0]的值"<<a[0]<<endl;//传递进来的a数组的值没有被拷贝到新的a中
ptr=&a[n-1];
cout<<"ptr地址:"<<ptr<<endl; //ptr的地址也发生了变化
cout<<"a[n-1]的值:"<<a[n-1]<<endl;
length+=increament;
}
*ptr=i;
ptr++;
n++;
}
}
return n;
}
int main()
{
int i,m,n,a[10];
cout<<"a地址:"<<a<<endl;
cout<<"a[0]地址:"<<&a[0]<<endl; //数组a的地址就是a[0]的地址
cout << "请输入m:"; //输入的m>48
cin >> m;
n=function(m,a);
cout<<"函数返回后a的地址:"<<a<<endl; //数a的地址又变回原来的地址了
for (i=0;i<n;i++) cout << a[i] << " ";
cout << endl << "n=" << n << endl;
cin>>m;
return 1;
}
结论:new是全新分配内存的并且不会自动拷贝数据,至于为什么a中原来的数据还存在通过测试我认为,主函在调用子函数的时,cpu将主函数的变量地址进栈保存,保护现场, 当子函数返回时,变量地址出栈,恢复现场。
/****************不知以上结论是否正确?*******************/