方法返回后内存被破坏
Memory being corrupted after method returns
我知道我只是错过了一些愚蠢的东西,但我很沮丧,我就是看不见它。当我对一个包含3个字段的文件运行下面的代码"field1;field2;field3"时,任务在retrieveTasks方法中被正确地打印出来。当该方法返回到main时,输出已损坏。我知道这很愚蠢,我只是想念它。我试过将CourseName, TaskDescription等改为数组而不是char*。我已经尝试过将fileString作为char*传入,我已经尝试过strcpy和没有。有人能给我指个方向吗?
const int MAX_STRING_LENGTH = 101;
const int MAX_TASK_ITEMS = 255;
const char NEWLINE = 'n';
const char DELIMETER[] = ";";
const char FILENAME[] = "tasks.txt";
struct Task {
char* CourseName;
char* TaskDescription;
char* DueDate;
char FileString[300];
void printTask() {
cout << CourseName << DELIMETER << TaskDescription << DELIMETER << DueDate << endl;
}
void initializeFromFileString(char fileString[]) {
strcpy(FileString, fileString);
CourseName = strtok(FileString, DELIMETER);
TaskDescription = strtok(NULL, DELIMETER);
DueDate = strtok(NULL, DELIMETER);
}
};
struct TaskList {
Task Tasks[MAX_TASK_ITEMS];
int TaskCount;
void initialize() {
TaskCount = 0;
return;
}
void addTask(Task task) {
Tasks[TaskCount] = task;
TaskCount++;
return;
}
void printTasks() {
for(int TaskNum = 0; TaskNum < TaskCount; TaskNum++) {
cout << TaskNum + 1 << ". ";
Tasks[TaskNum].printTask();
cout << endl;
}
return;
}
// Load data from the file. Will return -1 if it fails for any reason.
// Otherwise it returns the number of records read.
int retrieveTasks(const char* fileName) {
int isSuccessfulOpen = 0;
int recordsRead = 0;
ifstream inFile;
isSuccessfulOpen = openFile(inFile, fileName);
if(!isSuccessfulOpen) {
return -1;
}
// Read input file and store in appropriate arrays
while(inFile.eof() == false) {
char fileLine[MAX_STRING_LENGTH * 3];
Task task;
inFile.getline(fileLine, MAX_STRING_LENGTH * 3, NEWLINE);
inFile.ignore(UINT_MAX, NEWLINE);
task.initializeFromFileString(fileLine);
addTask(task);
recordsRead++;
}
inFile.close();
return recordsRead;
}
};
int main() {
bool isFinished = false;
TaskList taskList;
taskList.initialize();
taskList.retrieveTasks(FILENAME);
taskList.printTasks();
return 0;
}
int openFile(ifstream& inFile, const char* fileName) {
inFile.open(fileName);
// Veryify that the file is valid. If not print error message.
if(inFile.is_open() == false) {
cout << "File " << fileName << " does not exist. Please provide a valid file path." << endl;
return 0;
}
return 1;
}
// Open file for writing
int openFile(ofstream& outFile, const char* fileName) {
outFile.open(fileName);
// Veryify that the file is valid. If not print error message and exit.
if(outFile.is_open() == false)
{
cout << "File " << fileName << " does not exist. Please provide a valid file path." << endl;
return 0;
}
return 1;
}
CourseName
, TaskDescription
, DueDate
都指向在while
循环中创建的task
对象中存在的数组中的内存。由于task
对象是局部作用域,一旦retrieveTasks
完成执行,它们就会包含垃圾。
更改需要
-
你的任务计数总是比计数多一个-因此这个需要减少1。
for(int TaskNum = 0; TaskNum < TaskCount; TaskNum++) {
更改为
for(int TaskNum = 0; TaskNum < TaskCount -1 ; TaskNum++) {
-
从while循环中删除Task对象
-
AddTask
接受char *而不是Task。AddTask
调用initializeFromFileString
,使strcpy
对数组的Task对象内的字符串完成。strtok
也在字符串 上被调用改变 while(inFile.eof() == false) {
while(inFile) {
- 删除
inFile.ignore(UINT_MAX, NEWLINE);
struct Task {
char* CourseName;
char* TaskDescription;
char* DueDate;
char FileString[300];
void printTask() {
cout << CourseName << DELIMETER << TaskDescription << DELIMETER << DueDate << endl;
}
void initializeFromFileString(char fileString[]) {
strcpy(FileString, fileString);
CourseName = strtok(FileString, DELIMETER);
TaskDescription = strtok(NULL, DELIMETER);
DueDate = strtok(NULL, DELIMETER);
}
};
int openFile(ifstream& inFile, const char* fileName) {
inFile.open(fileName);
// Veryify that the file is valid. If not print error message.
if(inFile.is_open() == false) {
cout << "File " << fileName << " does not exist. Please provide a valid file path." << endl;
return 0;
}
return 1;
}
// Open file for writing
int openFile(ofstream& outFile, const char* fileName) {
outFile.open(fileName);
// Veryify that the file is valid. If not print error message and exit.
if(outFile.is_open() == false)
{
cout << "File " << fileName << " does not exist. Please provide a valid file path." << endl;
return 0;
}
return 1;
}
struct TaskList {
Task Tasks[MAX_TASK_ITEMS];
int TaskCount;
void initialize() {
TaskCount = 0;
return;
}
void addTask(char * t) {
Tasks[TaskCount].initializeFromFileString(t);
TaskCount++;
return;
}
void printTasks() {
for(int TaskNum = 0; TaskNum < TaskCount - 1; TaskNum++) {
cout << TaskNum + 1 << ". ";
Tasks[TaskNum].printTask();
cout << endl;
}
return;
}
// Load data from the file. Will return -1 if it fails for any reason.
// Otherwise it returns the number of records read.
int retrieveTasks(const char* fileName) {
int isSuccessfulOpen = 0;
int recordsRead = 0;
ifstream inFile;
isSuccessfulOpen = openFile(inFile, fileName);
if(!isSuccessfulOpen) {
return -1;
}
// Read input file and store in appropriate arrays
while(inFile) {
char fileLine[MAX_STRING_LENGTH * 3];
inFile.getline(fileLine, MAX_STRING_LENGTH * 3, NEWLINE);
addTask(fileLine);
printTasks();
recordsRead++;
}
inFile.close();
return recordsRead;
}
};
很明显,如果你用C++
而不是C inside classes
来写,整个程序会更简单,更少出错。
相关文章:
- 在 C++ 中访问数组负索引处的内存不会返回垃圾
- 共享内存:MapViewOfFile 返回错误 5
- 将内存分配返回值强制转换为 TYPE 数组
- 在先前调用 string::find 后添加内存分配和内存集会导致它返回 npos.为什么?
- 为什么 free() 函数不将内存返回给操作系统?
- 从函数返回时C++内存管理
- 字符 * 未从重载运算符或内存管理问题正确返回
- 如何返回定义良好的内存部分?例如来自图像数据的像素的颜色值
- 函数,返回变量c++占用的内存位置的大小
- 指针地址的内存偶尔更改了函数前和后返回
- 内存浪费?如果main()应该只返回0或1,那么为什么main是用int而不是短int甚至char声明的
- Clang++ 6.0 内存清理器未报告返回值指示条件分支的函数中的未初始化局部变量
- CUDA 中的递归返回非法内存访问
- C++返回数组而不进行动态内存分配?
- Visual C 运行时:Malloc将指针返回到已经使用的内存(包含实际字符串)
- C++动态分配内存返回数组
- 崩溃或被迫退出后,C++动态分配的内存返回
- 检测到严重错误 c0000374 - C++ dll 将指针断开分配给 C# 的内存返回
- C++:从堆栈内存返回std::字符串引用
- 在不终止程序的情况下将动态分配的内存返回给操作系统