【初学c++】创建对象数组s[10],只用到一部分,析构时报错

题目是创建一个学生类,包含名字,学号,分数,从键盘输入学生个数及其他信息,最后输出名字,学好,成绩,并求出平均分。
我认为是由于创建了对象数组s1[10],只用到一部分,剩余部分没有创建,所以析构时出错。求解答。

#include
#include
#include
using namespace std;
class s //定义一个学生类 包含名字 学号 分数 输出/入函数
{
char *name;
int no;
public:
int sc; //sc为分数 no为学号
sets(char *n,int nu,int s) //从键盘获取信息的函数
{
name=new char[10];
assert(name!=NULL);
strcpy(name,n);
no=nu;
sc=s;
}
~s()
{

        delete[]name;
        cout<<"destructor"<<endl;//检测是否正常析构
}
void show()
{
    cout<<name<<" "<<no<<" "<<sc<<endl;
}

};
int main()
{

int m,n,i,r,su;//r为学生人数,su为学生分数总和
cin>>r;
s s1[10]; //不确定学生人数,创建一个对象数组(假设学生人数小于11)
char *na;//sets函数的实参,表示学生名字
for(i=0;i<r;i++)
{
na=new char[10];
assert(na!=NULL);
cin>>na>>m>>n;
s1[i].sets(na,m,n);
delete[]na;
}

for(i=0;i {s1[i].show();}
cin>>su;
return 0;
}


首先你要知道C++类初始化的时候,因为没有构造函数,编译器会为其产生一个默认构造函数,为各个成员变量初始化一个值,而指针的初始化值有的会初始化程序逻辑地址的第一位对应的物理地址,gcc中应该是这样,而vs的编译器会是一个超大的无效负数,如我64位win7就是0xcccccccccccccccc。
因为你是把学生数组初始化为10个,这时候会调用10次默认构造函数,初始化10个默认的对象,然后你依次赋值,只要你的人数不到10个,肯定就会有name的指针没有被正确初始化,导致析构错误。
析构的时候是从后往前析构,即先析构s1[9],然后s1[8],s1[7]....这样,所以只要人数不到10,s1[9]的name肯定是个无效指针,析构时自然就要报错。

学号有多少位,char[10]最多装9位

C++中动态数组的使用遵循以下流程:

 int main()
{
  int size;

  std::cin >> size; //动态接收数组大小

  int *array = new int[size]; //定义数组

  .......... //其它代码

  delete [] array; //使用完毕释放内存

  return 0;
}

结合题目,动态对象数组的创建也是同样的方法

cin>>r;
s s1[10]; //不确定学生人数,创建一个对象数组(假设学生人数小于11)
可以修改为:

cin>>r;
s *s1 = new s[r];