使用*指针数组C ++设置构造函数和析构函数

时间:2014-12-08 22:52:47

标签: c++ arrays pointers constructor destructor

我使用int *studentsAge来存储年龄列表,double *marks[2]用于存储每位学生2个分数的列表。

基本上,我不确定如何设置我的constructordestructor

这是我的构造函数......

Students::Students()
{
  num = 0;
  studentsAge = NULL;
  marks[2] = NULL;
}

我在这个函数中使用了两个指针数组......

void Students::storeValues(int num)
{
   this->num = num;
   studentsAge = new int[num];
   for(int i=0; i<num; i++)
   {
     studentsAge[i] = i;
     marks[i] = new double[num]
   }
}

这是我的析构函数......

Students::Students()
{
   for(int i=0; i<num; i++)
   {
      delete[] marks[i];
      delete[] studentAge[i];
   }
   delete[] marks;
   delete[] studentAge
}

我不确定我的constructordestructor是否正确,我可以怀疑某处有内存泄漏。我对指针不是很好,但如果有人能告诉我哪里出错了,我会很感激

4 个答案:

答案 0 :(得分:1)

将每个学生聚集在一起是一个更好的设计:

struct Student
{
    int marks[2];
    int age;
};

然后存放一个学生容器:

struct Students
{
    std::vector<Student> students;
    void storeValues(int num);
}

您的功能如下:

void Students::storeValues(int num)
{
    students.resize(num, Student());   // zero-initialized students!

    for(int i=0; i<num; i++)
        students[i].age = i;
}

这样你就不需要在五条规则中编写任何析构函数或任何其他函数,这样就减少了出错的机会,避免浪费时间编写样板代码。

答案 1 :(得分:0)

没有理由使用2元素标记数组。让自己轻松自如,将其改为2倍*标记0和标记1。

double* marks0;
double* marks1;

但是,如果要继续当前路径,首先需要正确初始化标记:

Students::Students()
{
    num = 0;
    studentsAge = NULL;
    marks[0] = NULL;     //clear the pointer to the first array of marks
    marks[1] = NULL;     //clear the pointer to the second array of marks
}

现在您需要正确创建标记数组:

void Students::storeValues(int num)
{
   this->num = num;
   studentsAge = new int[num];
   marks[0] = new double[num];
   marks[1] = new double[num];
   for(int i=0; i<num; i++)
   {
     studentsAge[i] = i;  //what is this doing?  each student's age is the same as his/her index?
     marks[0][i] = 0;     //initialize the first mark for student i
     marks[1][i] = 0;     //initialize the second mark for student i
   }
}

最后你需要正确销毁数组:

Students::~Students()
{
   delete[] marks[0];
   delete[] marks[1];
   delete[] studentsAge;
}

答案 2 :(得分:0)

我猜你的学生课程就你的主要领域而言看起来有点像这样:

class Students
{
   private:
    static const int maxNumberMarks = 2;  //the maximum number of marks that can be stored per student
    int numStudents;                      // the count of the number of students
    int* studentsAge;                     // an array of each students ages   
    double* marks[maxNumberMarks];        // an array of arrays to store each student mark
}

在这种情况下,您的默认构造函数几乎是正确的。您只需要正确初始化标记数组。

Students::Students()
{
   num = 0;
   studentsAge = NULL;
   for( int markIndex = 0; markIndex  < maxNumberMarks; ++markIndex )
   {
       marks[markIndex ] = NULL;
    }
}

你的初始化功能有点混乱。

首先,我会将输入数字arg重命名为numStudents,以免与同名的成员变量混淆。

其次,您需要将数组的分配与初始化分开

void Students::storeValues(int numStudents )
{
  this->num = numStudents ; //store off how many students we are handling.

  //allocate 3 storage arrays for each student. The age array and 2 mark arrays 
  studentsAge = new int[numStudents ];
  for( int markIndex =0; markIndex < maxNumberMarks; ++markIndex)
  {
     marks[markIndex] = new double[numStudents];
  } 

  //now init the arrays to something 
  for(int studentIndex=0; studentIndex < numStudents ; studentIndex++)
  {
     studentsAge[studentIndex] = studentIndex;
     for( int markIndex =0; markIndex < maxNumberMarks; ++markIndex)
     {
        marks[markIndex][studentIndex] = 0.0; //zero seems a reasonable initial value.
     }
  }
}

最后,为了获得析构函数,您只需要镜像分配数组的代码。

~Students()
{
   //delete the marks arrays 
    for( int markIndex =0; markIndex < maxNumberMarks; ++markIndex)
    {
       delete[] marks[markIndex];
       marks[markIndex] = NULL;
     } 

   //delete the ages array
   delete[] studentsAge;
   studentsAge = NULL;
}

随着您的代码的增长,您可能希望为每个学生存储不同的数据,我建议您创建一个Student类来帮助简化所有内容。

class Student
{
  private:
    static const int maxNumberMarks = 2;  //the maximum number of marks that can be stored per student
    int age; //the age of the student
    double marks[maxNumberMarks];
 }

假设您使用适当的默认构造函数充实了Student数组,这将所有分配简化为Students类中的一个位置

Students
{
   Student* studentsArray;  //dynamically  allocated array of student info
   int numStudents;     
 }

 void Students::storeValues(int numStudents )
 {
    this->num = numStudents ;
    studentsArray = new Student[numStduents];
 }

 ~Students()
 {
   delete[] studentsArray;
   studentsArray = NULL;
 }

如果你使用std :: vector代替分配的数组,你甚至不必担心分配和释放它。

答案 3 :(得分:0)

简短回答:

您需要撰写以下内容:

Students::Students()
{
  num = 0;
  studentsAge = NULL;
  marks[0] = NULL;
  marks[1] = NULL;
}

void Students::storeValues(int num)
{
   this->num = num;
   studentsAge = new int[num];
   marks[0] = new int[num];
   marks[1] = new int[num];

   for(int i=0; i<num; i++)
   {
     studentsAge[i] = i; // this is where you give each student an age, are you sure you want to use i?
     // here you can put grade assignments as follows:
     marks[0][i] = val1; // first mark for student i
     marks[1][i] = val2; // second mark for student i
   }
}

Students::~Students()
{
   delete[] marks[0];
   delete[] marks[1];
   delete[] studentsAge;
} 

答案很长:

您似乎需要了解指针是什么以及数组是什么。

当你在类声明中放入double *marks[2]时,它将保留一个大小为2的数组 附加到类的每个实例的指针。您不需要将[2]放在构造函数中。

指针是一个变量,它保存内存中保留地址块的第一个地址。这意味着当您指定指针时,需要为其指定一个内存地址。要将值写入存储在指针中的地址,请在变量前使用*字符。

int num = 2;
int* p;

p = &num; // p will hold the address of num.  Any changes to p's value will be reflected in num

p = new int; // p is assigned a new address
*p = num; // the address that p points to will hold 2 (the value in num), but if that value is changed, num will still hold 2

如果要将数组分配给p,可以使用new关键字。这将分配内存 供您的程序使用。别忘了解除分配。

size = 10;
p = new int[size];

现在您可以通过将其视为数组或指针算术来引用p中的值, 我现在不会进入。

p[0] = 1; // the first 
p[5] = 56;

指针和数组之间的区别在于数组分配和释放由。处理 编译器并且需要在编译时具有固定大小。指针分配和释放由用户处理,其大小在运行时定义。