[英]C++: Program crashes when trying to print const char* array
我有一個程序,可以讓用戶輸入他們的姓名,年齡和所參加的課程。 這些類作為chars的二維數組存儲在main()函數中,然后將它們傳遞到Student類中的一個函數,該類將該數組復制到名為m_CourseNames的公共成員const char *數組中。 我已經在CLion中使用調試器驗證了此過程已成功完成。
但是,當我嘗試遍歷m_CourseNames數組並將其內容打印到屏幕時,我得到exit code 11
,並且程序崩潰。
我嘗試通過以下方式將陣列打印到屏幕上:
在主要功能中:
for (int count = 0 ; count < 9 ; count++) cout << student.m_CourseNames[count] << " ";
在學生類的成員函數中,通過student.getCourses();
進行調用student.getCourses();
:
for (int count = 0 ; count < 9 ; count++) cout << m_CourseNames[count] << " ";
在與1中相同的方法的重載運算符函數內部(請參閱代碼以了解我為什么在此處嘗試)
試圖將const char *數組打印到屏幕上的所有三種方法在程序完成之前都導致了以下錯誤代碼:
如果數組是一個公共成員變量,我不知道為什么它不會迭代。 調試器驗證了所有類都已正確存儲在其中,因此這不是addCourses()函數的責任。
請參閱下面的整個程序(注釋掉的所有內容都是試圖將陣列打印到屏幕上的嘗試):
--main.cpp--
#include <iostream>
#include "Student.h"
using namespace std;
int main()
{
char input[10][128] = {(0),(0)};
char name[128] = {0}, student_check = ' ';
int age = 0, count = 0;
cout << "\nPlease state your name and age:\n\n";
cout << "Name: ";
cin.getline(name, 128);
cout << "Age: ";
cin >> age;
cin.clear();
cin.ignore();
cout << "\n\nThanks!\n\nAre you a student? (Y/N): ";
cin.get(student_check);
switch (student_check)
{
case 'y':
case 'Y':
{
Student student;
student.setName(name);
student.setAge(age);
char course_check = ' ';
cout << "\n\nWhat course(s) are you taking?"
<< " (Enter the course prefix and number without any spaces): \n\n";
while (tolower(course_check) != 'n') {
cin.clear();
cin.ignore();
cout << "Course #" << count + 1 << ": ";
cin.getline(input[count], 128);
student.addCourse(input[count], count);
if (student.addCourse(input[count], count))
{
cin.clear();
cout << "Do you want to enter another course? (Y/N): ";
cin.get(course_check);
count++;
}
else
{
cout << "You have exceeded the number of courses you are allowed to enter" << endl << endl;
course_check = 'n';
}
cout << student;
student.getCourses();
//for (int count = 0 ; count < 9 ; count++)
// cout << student.m_CourseNames[count] << " ";
}
}
default:
break;
}
}
--Student.h---
#ifndef PA2_STUDENT_H
#define PA2_STUDENT_H
#include "Person.h"
#include <ostream>
class Student : public Person
{
public:
Student();
Student(const char* []);
bool addCourse(const char*, int);
void getCourses();
friend std::ostream& operator <<(std::ostream& os, const Student& student);
const char* m_CourseNames[10];
};
#endif
--student.cpp--
#include "Student.h"
#include <iostream>
using namespace std;
Student::Student() {}
Student::Student(const char* m_CourseNames[])
{
m_CourseNames[10] = {0};
}
bool Student::addCourse(const char* course, int index)
{
if (index < 9)
{
m_CourseNames[index] = course;
return true;
}
if (index >= 9)
return false;
}
void Student::getCourses()
{
cout << ", Courses: ";
for (int count = 0 ; count < 9 ; count++)
cout << m_CourseNames[count] << " ";
}
std::ostream &operator<<(std::ostream& os, const Student& student) {
os << "Name: " << student.m_Name << ", Age: " << student.m_Age;// << ", Courses: " << Student::m_CourseNames;
//cout << ", Courses: ";
// for (int count = 0 ; count < 9 ; count++)
// cout << m_CourseNames[count] << " ";
return os;
}
您正在迭代尚未填充的數組中的條目。 您想要類似的東西:
void Student::getCourses()
{
cout << ", Courses: ";
for (int count = 0 ; count < index ; count++)
cout << m_CourseNames[count] << " ";
}
而且,正如Arun指出的那樣,您正在訪問數組。 您無法訪問十個條目數組的第11個元素,而第10個條目是第11個元素(因為第一個是0)。
您的代碼確實很糟糕,盡管有很多原因。 主要問題是您的Person
類隱藏了它不擁有的內存的指針 ,這使該類很難使用。 為什么不使用std::string
呢?
在Student::Student(const char* m_CourseNames[])
,您將超越數組m_CourseNames[10] = {0}; //Index is in [0..9] range
m_CourseNames[10] = {0}; //Index is in [0..9] range
此外,您在哪里為const char *
m_CourseNames
指針數組分配空間?
請考慮使用std::array
和std::string
而不是C類型的數組和指針。
student.m_CourseNames
是一個指向char的指針數組。 這意味着您將獲得一堆指針。 您沒有指向任何存儲空間,因此,如果指針未指向某個有效存儲空間,則程序將運行到雜草中。 誰知道會發生什么。 也許找到丟失的海盜寶藏。 也許被龍吃掉了。 可能會使程序崩潰。
student.m_CourseNames
由student.addCourse(input[count], count);
它提供了一個指針(下一個學生將覆蓋它,所以這是個壞主意)以及將更新m_CourseNames的索引。 這也是一個壞主意,但不是致命的主意。 類的目的之一是它們控制自己的數據,因此Student應該維護該索引。
假設我們添加了三個路線:A,B和C。for for (int count = 0 ; count < 9 ; count++)
將嘗試打印9(索引0到8),這意味着至少要拍攝六張照片導致程序崩潰的不確定行為。
解決方案:
不要使用char數組。 使用std :: string。
如果必須使用char數組,請提供存儲並將源復制到存儲中。 這樣,您就知道它是安全的,除非您想要或做一些愚蠢的事情,否則不會被覆蓋。
不要使用指針數組。 使用std :: vector(以及實際數據,而不是數據指針)。 向量隨着您添加的增加而調整大小,並且始終知道其包含多少項。 如果不能使用向量,請堅持使用數組,而不要使用指針數組。 如果可能,使用std :: string數組。
跟蹤存儲在列表中的項目數,以免行進中。 Vector為您做到了。
封裝您的類數據。 學生應了解並管理學生的所有事情。 沒有人會告訴學生將其放在哪里,只說它有課程。 當您要打印學生的數據時,請學生為您打印。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.