关于c++动态数组的难题请问下面这个程序错在哪,为什么?是不能在循环里定义动态数组吗?还是其他什么问题呢?
关于c++动态数组的难题
请问下面这个程序错在哪,为什么?是不能在循环里定义动态数组吗?还是其他什么问题呢?
是不是动态数组也一定要设定长度呢?如果是那么为什么下面的第二个程序又可以正常运行呢?
请知道的大师帮帮忙解答下:究竟是什么问题导致第一个程序不能正常运行呢?
#include<iostream>
using namespace std;
int main()
{
int n,i,t,j;
while(cin>>n)
{
int*a=new int[];
for(i=0;i<n;i++)
cin>>a[i];
for(t=n-1;t>0;t--)
{
for(i=0;i<t;i++)
if(a[i]>a[i+1])
{
j=a[i];
a[i]=a[i+1];
a[i+1]=j;
}
}
cout<<sizeof(a)<<endl;
for(i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
delete[] a;
}
return 0;
}
为什么上面这个程序有错误,而下面这个程序却正常呢
#include<iostream>
using namespace std;
int main()
{
int n,i,t,j;
int*a=new int[];
while(cin>>n)
{
for(i=0;i<n;i++)
cin>>a[i];
for(t=n-1;t>0;t--)
{
for(i=0;i<t;i++)
if(a[i]>a[i+1])
{
j=a[i];
a[i]=a[i+1];
a[i+1]=j;
}
}
cout<<sizeof(a)<<endl;
for(i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
delete[] a;
return 0;
}
[解决办法]
不知道楼主的第二个程序怎么运行成功的,或许只是一个偶然事件,或者,你用的编译器对申请的内存会做些处理
[解决办法]
new 数组的时候,需要给大小
[解决办法]
第一个 程序 崩溃的地方是在delete语句那行。
第二个程序 是一直没有 执行到“delete[] a;”这一句
你的程序 一直在 兜“while(cin>>n)” 循环,命令行中还在提示你输入呢
你乌龙了,结贴吧。。。
[解决办法]
[解决办法]呵呵 很不幸 我也不知道为什么,你的程序,按照常人去理解,两个都该崩溃的。
new int[]这种写法,真是匪夷所思。
但是我能解答你new了不delete的问题
new了但不delete,是可以的,不过这是一个程序员的素质问题罢了,大不了,你吃内存吧,大不了,你卡死吧 但不会让程序崩溃
所谓程序的崩溃,并不是因为new了之后不delete导致的而是其他原因,比如new失败就用指针,再比如delete之后还在用野指针,再比如你用指针游走访问堆内存的时候,写了new之外的那些空间
[解决办法][解决办法]错在17楼非法访问
void * operator new[]( size_t cb )
{
void *res = operator new(cb);
RTCCALLBACK(_RTC_Allocate_hook, (res, cb, 0));
return res;
}
强大的F11告诉我cb=0*4;
还有个好玩的就是C/C++无法知道指针所指的内存容量,sizeof(整型指针)在32位下恒等于4
还有个好玩的就是delete[]通过new时的cookie域得知须释放的空间长度
[解决办法]从28楼开始把楼主往深渊里带啊 一个new操作符而已
不知道谁要从头实现动态数组?谁要实现STL Vector?或者实现那些就可以解决多数问题了?试想一个连基本调试手段都不会的新人去实现这些?
当然多看些书没坏处,可是问题还不至于那么复杂
cin>>n;
int*a=new int[];
for(i=0;i<n;i++)
...
for(i=0;i<t;i++)
...
a[i+1]=j;
n输入10000则i的范围有多大?a有多宽?a[i+1]越界了没有?
就单步走了一行,基本可以说VS10下的实现方式了:就是传入0,你要求0字节?实际能分配多少
代码是微软的,如27楼所说,不必细究,cb可以百度匈牙利命名法,大概是要求分配的字节数,callback没有继续跟,因为VC6和VS10实现代码都不一样,而且楼主连自己都不知道跑起来后a有多宽,这种代码应该丢在一边
不免想起(i++)+(i++)的大量帖子...
引用别人的话:请不要迷信书,编译器...眼过千行不如单步一行
如果老师都在说假话,能靠的住的只有你的cpu
------解决方案--------------------
在VS2010或其它版本中:
int*a=new int[]; 是申请了一个长度为0的空间,而不是申请了一个能无限访问的空间。虽然返回也有地址值,但是却没有分配有效的空间,因此任何对元素的访问都是有问题的。
然而,“有问题”并不一定会出错,因为你出的错系统不一定能立即检查出来。
楼主在第二个程序里输入“1 1 ^Z”试试,注意“^Z”是用“CTRL + Z”键输入的特殊字符。
“运行时才确定大小”的意思是你可以在运行时传入一个参数来设置大小,例如 int* a = new int[n];不是说运行的时候会根据你访问的地址来给你无限的访问权力。
按楼主现在学习的进度来看,《STL源码剖析》暂时不适合你,可以放到半年左右之后再去看,先存着好了。
我们把内存理解为一块块的农田好了,规则是这样:
村规规定每个人在出生的时候都能享受2块农田,直到你死去。这种就是int a[2];
村规又规定每个人在世的时候可以向村长申请更多的田地,这就是动态内存分配。
所有人在需要种东西的时候,向村长申请田地大小,然后村长批文件,把其中的几块农田交给你使用,这就是new的功能。
村长不会根据你用了哪几块田而把那几块田分给你,而是你自己先申请再使用,这就是系统的内存使用规定。
你在申请到农田之后,根据农田的编号开始往田里种东西,但是你不小心把邻近的农田也种上了。这就是越界访问。
如果在你收获食物之前,村长碰巧都没有把你越界访问的农田分给别人用,那么你还是可以收获到你种的果实。这就是违规了不一定会出错,但是你不会永远都这么好运气的。
如果你不但把邻近的田种了,还种到了别村的土地里,那么别村的村长可能就会找你交涉了。这就是违法,系统能感知到。
你在收获果实之后,要把农田还给村里,供它人使用,这就是delete。
如果你不归还农田,每次需要种粮食都去找村长要新农田,这就是new之后不delete。但是后果可想而知,种太多次粮食之后,农田全都被你占了,别人都种不成。最后全村几乎都没有收成,所以用完之后,及时归还是个好习惯。
当你人死之后,村长就会翻着清单把所有分配给你的田地收回,这就是程序结束之后的自动内存回收。
这样够清楚么?