我正在尝试为一个hw任务编写一个多线程程序。到目前为止,我所有的程序中都有一些代码来读取一组二进制数据文件(为分配提供),并将这些文件的内容读入2D数据阵列。程序构建时没有任何错误,但是当我运行它时,它会在从指定的元数据文件中读取DAT文件的名称后退出。我无法弄清楚我哪里出错了,任何帮助都将不胜感激!
这是我收到的错误:
“MultiThreading.exe中0x773a5c0c(ntdll.dll)的未处理异常:0xC0000374:堆已损坏。”
其次是:
“MultiThreading.exe中0x7730d1ed(ntdll.dll)的未处理异常:0xC0000005:访问冲突读取位置0x0000001e。”
这是我的代码,我很肯定那里有一个错误,但我是C ++编程的新手,我找不到它: - /
// MultiThreading.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include <Windows.h>
//include the custom header file
//#include <Engine.h>
using namespace std;
using namespace System;
using namespace System::Threading;
void ReadData(char * filename, int * nVals, float ** dataVals);
int ReadMeta(char * metaFile, int * nThreads, int * nFiles, string ** filenames);
void main(int argc, char * argv[])
{
//set default # of threads in case no user input is provided
int nThreads = 12;
//assign default metainfo file in case no user input is provided
char metaFile[200] = "DataFiles\\MetaInfo.txt";
//check for console user input for threads and metainfo file, if available
if (argc > 1)
{
nThreads = atoi(argv[1]);
if (argc > 2)
{
strcpy_s(metaFile, argv[2]);
}
}
//initialize # of files and string to hold filenames
int nFiles = 0;
string * filenames = NULL;
//read metainfo to get # of data files and file names
//Call ReadMeta(metaFile, &nThreads, &nFiles, &filenames);
//check for errors in reading metainfo
if (ReadMeta(metaFile, &nThreads, &nFiles, &filenames) == 0)
{
cout << "Error reading data files and/or requesting threads."
<< "\nOperation aborted!\n\n";
}
//read file data into multiple arrays
for (int i = 0; i < nFiles; i++)
{
cout << "Reading contents of data file " << filenames[i];
int nVals = NULL;
float * dataArray = NULL;
//convert string to char for filename to pass to function
char * binFile = (char*)filenames[i].c_str();
//read files and write to dataArray
ReadData(binFile, &nVals, &dataArray);
}
//release memory
if (filenames) delete[] filenames;
filenames = NULL;
system("pause");
}
int ReadMeta(char * metaFile, int * nThreads, int * nFiles, string ** filenames)
{
ifstream inputFile(metaFile);
//check for error locating metainfo file
if (!inputFile)
{
cout << "ERROR: Target file " << metaFile << " was not found.\n";
return 0;
}
//assign # of files to *nFiles
inputFile >> (*nFiles);
//check if data files are listed in metainfo file
if (*nFiles < 1)
{
cout << "No data files are provided!\n";
inputFile.close();
return 0;
}
else if (*nFiles < 2)
{
cout << "NOTE: Only ONE data file is available.\n\n";
}
//print number of data files to screen
else
{
cout << *nFiles << " data files are available.\n\n";
}
//check for # of threads being requested and set to default value if reqd
if ((*nThreads <= 0) || (*nThreads > *nFiles))
{
cout << "WARNING: Invalid number of threads requested.\n"
<< "Number of threads truncated to valid range 2 - " << *nFiles
<< "\nDefault value is 2 threads.";
*nThreads = 2;
}
//print # of data files and threads to screen
cout << *nFiles << " files are available.\n"
<< *nThreads << " threads have been requested.\n"
<< "Each file is assigned to a separate thread.\n";
//adjust number of threads
if (*nThreads > *nFiles)
{
*nThreads = *nFiles;
cout << "Fewer threads will be created due to insufficient data files."
<< "That is, only " << *nThreads << " threads will be created.\n\n";
}
else if (*nThreads < *nFiles)
{
*nFiles = *nThreads;
cout << "Fewer files will be used to meet the thread requirements."
<< "That is, only " << *nFiles << " files will be used for "
<< *nThreads << " threads.\n\n";
}
//assign file names to *filenames
*filenames = new string[*nFiles];
for (int i = 1; i <= (*nFiles); i++)
{
inputFile >> (*filenames)[i];
cout << "\nData file #" << i << ": " << (*filenames)[i].c_str() ;
}
//close metainfo file
inputFile.close();
cout << endl << endl;
return 1;
}
void ReadData(char * filename, int * nVals, float ** dataVals)
{
//open the file "filename" passed to the function
FILE * thisFile;
fopen_s(&thisFile, filename, "rb");
//read the number of values contained in the file
fread(nVals, sizeof(int), 1, thisFile);
//create an exact sized array to hold the values contained in the file
*dataVals = new float[*nVals];
//read values from file to array
fread(*dataVals, sizeof(float), *nVals, thisFile);
//close the file
fclose(thisFile);
}
我在Windows 10 x64系统上使用Visual Studio Community 2015。该程序配置为Win32。
绝对任何帮助或任何可以帮助我解决这个问题的方向都将受到极大的赞赏。
谢谢!
答案 0 :(得分:2)
*filenames = new string[*nFiles];
for (int i = 1; i <= (*nFiles); i++)
{
inputFile >> (*filenames)[i];
cout << "\nData file #" << i << ": " << (*filenames)[i].c_str() ;
}
C ++中的数组以索引0开头。包含五个元素的数组filename
包含元素filename[0]
到filename[4]
。
在这种情况下,您将分配一个包含五个字符串的数组,但不是通过filename[0]
初始化filename[4]
,而是尝试初始化filename[1]
到filename[5]
。< / p>
由于filename[5]
不存在,因此会导致未定义的行为。您已观察到的运行时崩溃是此未定义行为可能导致的结果之一。