c++ - 未处理的异常 : Corrupted heap and access violation reading memory location

标签 c++ multithreading

我正在尝试为硬件分配编写一个多线程程序。到目前为止,我的程序中只有一些代码可以读取一组二进制数据文件(为作业提供),并将这些文件的内容读入二维数据数组。该程序构建没有任何错误,但是当我运行它时,它会在从指定的元数据文件中读取 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 配置的。

绝对非常感谢任何可以帮助我解决此问题的帮助或指导。

谢谢!

最佳答案

*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[4] 初始化 filename[0],您将尝试初始化 filename[1]filename[5]

由于 filename[5] 不存在,这会导致未定义的行为。您观察到的运行时崩溃是这种未定义行为的可能结果之一。

关于c++ - 未处理的异常 : Corrupted heap and access violation reading memory location,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33948443/

相关文章:

c++ - 为什么代码块显示错误?

c++ - 为什么#pragma once 不防范多个非 constexpr 定义?

c++ - CUDA 直方图 reduce_by_key 失败

c++ - 如何阻塞线程直到一个函数在另一个线程中返回?

java - Thread.stop() - 已弃用

c++ - 使用 CGL 编译 MacOS 应用程序

c++ - 在方法C中设置常量字符串相等?

multithreading - 如何在套接字接收事件后更新Blazor(托管)

java套接字如何从两个不同的线程发送数据

c - 在动态 DLL 中使用线程私有(private)变量?