这是我要问的第一个问题,请在必要时仔细检查我:)
我试图在学校解决C ++课程的问题。我遇到了一个我无法理解的错误。我正在编程中接受我的宝贝步骤。
作业说:
两个班级,
使用的继承机制,
数据库让学生使用动态内存分配,
一种在不使用高级数据结构的情况下扩展数据库的方法,
为已创建类的对象重载流操作符。
这是我的代码:
#include <conio.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
class Person
{
protected:
char Name[20];
string Surname;
int Age;
public:
virtual void whoAmI()=0;
friend ostream &operator<< (ostream &out_, Person &s); // stream overl.
friend istream &operator>> (istream &in_, Person &s);
friend void resizeArr(Person* oldList, int oldSize, int newSize); // array enlarge
};
class Student :public Person
{
public:
Student(){}
Student(char name[], string surname, int age )
{
strcpy(Name, name);
Surname = surname;
Age = age;
}
virtual void whoAmI() // basically replaced by overloaded ostream
{
//cout << "I am a student\nMy name is " << name <<" "<< surname << "; I'm "<< age << " years old.";
cout << Name << endl;
cout << Surname << endl;
cout << Age << endl;
}
};
istream &operator>> (istream &in_, Person &s) // through reference: stream object and overloading object
{
cout << "New student record: "<< endl;
cout << "Name: " << endl;
in_ >> s.Name;
cout << "Surname: " << endl;
in_ >> s.Surname;
cout << "Age: " << endl;
in_ >> s.Age;
cout << endl;
return in_;
}
ostream &operator<< (ostream &out_, Person &s)
{
out_ << "Name:\t\t" << s.Name << endl << "Surname:\t" << s.Surname << endl <<"Age:\t\t" << s.Age << endl;
return out_;
}
void resizeArr(Student* oldList, int oldSize, int newSize)
{
Student *newList = new Student[newSize];
for(int i = 0; i < oldSize; i++) // COPYING
{
newList[i]=oldList[i];
}
for(int i = oldSize ; i < newSize ; i++) // init rest as blank students to avoid errors
{
newList[i] = Student( "undef" , "undef", 0);
}
delete [] oldList; // free memory used for old array
oldList = newList; // reset pointer to new array
}
int main()
{
int initSize = 2;
int plusSize = 4;
Student *list1 = new Student[initSize];
for (int i=0; i<initSize; i++){ // initialize each cell as a blank student
list1[i] = Student( "undef" , "undef", 0);
}
for (int i=0; i<initSize; i++) // display initial array
{
cout << list1[i] << endl << "------------------------------" << endl; // for the sake of console output clarity
}
resizeArr(list1, initSize, plusSize); // FUNCTION CALL
cout << endl << "\tEnlarger database: " << endl << endl; // for the sake of console output clarity
for (int i=0; i<plusSize; i++) // display enlarged array
{
cout << list1[i] << endl << "------------------------------" << endl; // for the sake of console output clarity
}
getch();
return 0;
}
我之前使用整数数组原型化了这样一种机制,它起作用了......现在我因为一个未知原因而崩溃了。
请指出正确的方向。
编辑:
程序编译并运行,新数组似乎保存旧数组的前两个元素,并且到达第一个新元素时,程序崩溃(内存单元似乎在拖着我并且持有一个笑脸)。
复制前两个Student
个对象,第三个元素导致错误:
答案 0 :(得分:0)
问题在于调整大小函数的定义:
void resizeArr(Student* oldList, int oldSize, int newSize)
除非另有说明,否则传递给函数的所有参数均按值计算。即使第一个参数是一个指针,它只允许修改它指向的内存,而不是指针本身。
您需要将第一个参数的声明更改为Student **
,并在方法中更改代码以处理双重取消引用,或将其更改为Student*&
。
我怀疑你很幸运它适用于整数。
答案 1 :(得分:0)
您正在将指向学生列表的指针传递给resizeArr
例程,即void resizeArr(Student* oldList, int oldSize, int newSize)
,但不是指向指针的指针。
因此,在resizeArr中为指针分配一个新的/不同的内存块会让resizeArr中的变量指向新地址,但是传递给resizeArr的指针(即list1
)不会改变。
我建议将逻辑更改为Student* resizeArr(Student* oldList, int oldSize, int newSize)
并将其称为list1 = resizeArr(list1, initSize, plusSize);
这类似于void* realloc (void* ptr, size_t size);
的签名。