Я очистками игрушечной программы, которую я написал для класса с помощью Xcode 5. Части задания было получить знакомство с динамическим распределением памяти (что означает, что сусла использовать new
и delete
несмотря тот факт, что он действительно будет работать без него). Я получаю:C++: указатель освобождение не было выделен
HeapOfStudents(67683,0x7fff769a6310) malloc: *** error for object 0x100300060: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug
ошибка происходит:
Student::~Student() {
delete firstName; // <- on this line
delete lastName;
delete address;
delete birthDate;
delete gradDate;
delete gpa;
delete crHours;
}
, который называют ...
int main() {
string line = "";
vector<Student> students;
//
//Create new students from file
//
ifstream data_file ("heapData");
if (data_file.is_open()) {
while(getline(data_file, line))
students.push_back(*new Student(line)); <- inside this call here
data_file.close();
}
else return 0;
Полный Student
класс ниже.
Важно отметить, что я заметил, что в то время как каждый line
получает правильно толкнул к вектору, когда следующий Student
получает толкаемом, предыдущий Student
внутри вектор повреждается. Я вижу ошибку malloc
всегда на третьей итерации цикла (файл имеет 50 строк).
Программа работает без исключения, если я меняю vector<Student>
на vector<Student *>
и student.push_back(*new Student(line))
на student.push_back(new Student(line))
.
Мой вопрос: Может кто-нибудь объяснить, что на нижнем уровне происходит внутри этого цикла, что создает эту ошибку?
Я думаю, что *new Student(line)
использует тот же указатель каждый раз, так в каждой итерации получает данные повреждены, так как он освобожден (хотя это объяснение вызывает вопросы), в то время как new Student
возвращает новый указатель каждый раз, сохраняя данные, был передан students
. Я думаю, что, возможно, мне нужно написать конструктор копий ... Это только моя догадка.
Это Student
класс. Address
и Date
также являются обычными классами, которые довольно похожи. Я не включил их, потому что они, похоже, не являются частью проблемы.
//Constructors
Student::Student() {
firstName = new string("Testy");
lastName = new string("Testerson");
address = new Address("000 Street St", "", "Citytown", "State", "00000");
birthDate = new Date("01/02/9876");
gradDate = new Date("01/02/6789");
gpa = new string("10.0");
crHours = new string("300");
}
Student::Student(string FN, string LN, string L1, string L2, string C, string S, string Z, string BD, string GD, string GPA, string Hr) {
firstName = new string(FN);
lastName = new string(LN);
address = new Address(L1, L2, C, S, Z);
birthDate = new Date(BD);
gradDate = new Date(GD);
gpa = new string(GPA);
crHours = new string(Hr);
}
Student::Student(string line) {
set(line);
}
//Destructors
Student::~Student() {
delete firstName;
delete lastName;
delete address;
delete birthDate;
delete gradDate;
delete gpa;
delete crHours;
}
//Member Functions
void Student::set(string line) {
firstName = new string(line.substr(0, line.find_first_of(",")));
line = line.substr(line.find_first_of(",") + 1, string::npos);
lastName = new string(line.substr(0, line.find_first_of(",")));
line = line.substr(line.find_first_of(",") + 1, string::npos);
address = new Address();
address->setLine1(line.substr(0, line.find_first_of(",")));
line = line.substr(line.find_first_of(",") + 1, string::npos);
address->setLine2(line.substr(0, line.find_first_of(",")));
line = line.substr(line.find_first_of(",") + 1, string::npos);
address->setCity(line.substr(0, line.find_first_of(",")));
line = line.substr(line.find_first_of(",") + 1, string::npos);
address->setState(line.substr(0, line.find_first_of(",")));
line = line.substr(line.find_first_of(",") + 1, string::npos);
address->setZip(line.substr(0, line.find_first_of(",")));
line = line.substr(line.find_first_of(",") + 1, string::npos);
birthDate = new Date(line.substr(0, line.find_first_of(",")));
line = line.substr(line.find_first_of(",") + 1, string::npos);
gradDate = new Date(line.substr(0, line.find_first_of(",")));
line = line.substr(line.find_first_of(",") + 1, string::npos);
gpa = new string(line.substr(0, line.find_first_of(",")));
line = line.substr(line.find_first_of(",") + 1, string::npos);
crHours = new string(line.substr(0, line.find_first_of(",")));
line = line.substr(line.find_first_of(",") + 1, string::npos);
}
void Student::printReport() {
cout << *lastName << ", " << *firstName << ", " << address->getAddress()
<< ", " << birthDate->getDate() << ", " << gradDate->getDate()
<< ", " << *gpa << ", " << *crHours << endl;
}
void Student::printName() {
cout << *lastName << ", " << *firstName << endl;
}
string Student::getName() {
return string(*lastName + ", " + *firstName);
EDIT Вот копировальную конструкторы и операторы присваивания, которые я написал для класса студент должен кто-то быть заинтересован в том, чтобы/критикуя их:
Student::Student(const Student & student){
firstName = new string(*student.firstName);
lastName = new string(*student.lastName);
address = new Address(*student.address);
birthDate = new Date(*student.birthDate);
gradDate = new Date(*student.gradDate);
gpa = new string(*student.gpa);
crHours = new string(*student.crHours);
}
Student& Student::operator=(const Student & student) {
return *new Student(student);
}
Почему вы даже используете указатели здесь? Просто 'firstName' будет' string' вместо 'string *'. – cdhowie
@cdhowie: см. Первый абзац. Это упражнение для изучения управления памятью. –
В современном C++ нет голых указателей. – user515430