未处理的异常:损坏的堆和访问冲突读取内存位置

时间:2015-11-26 23:34:18

标签: c++ multithreading

我正在尝试为一个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。

绝对任何帮助或任何可以帮助我解决这个问题的方向都将受到极大的赞赏。

谢谢!

1 个答案:

答案 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]不存在,因此会导致未定义的行为。您已观察到的运行时崩溃是此未定义行为可能导致的结果之一。