堆腐败和随机断点

时间:2015-12-26 04:50:33

标签: c++ memory mfc breakpoints heap-corruption

我正在努力完成我的简单档案系统。我使用MFC应用程序来处理构建存档文件。唯一的问题是一个函数似乎导致错误,但Visual Studio无法告诉我在哪里或为什么这样我迷失了怎么办。即使在搜索之后,这些解决方案都不适用于我。

bool UE_ArchiveLoad(UE_Archive * archive, char* path)
{

ifstream input = ifstream(path, std::ifstream::in | std::ifstream::ate | std::ifstream::binary);

char* Header = new char[3];
char version = 0;
if (input.fail())
{
    return false;
}
input.seekg(0, ios::beg);


input.read(Header, 3);
input.read(&version, 1);

string T = Header;
T = T.substr(0, 3);
Header = (char*)T.c_str();

if (strcmp( Header,UE_ARCHIVE_SIGNATURE)!=0)
{
    printf("INVALID SIGNATURE: ");
    cout << Header <<endl ;
    return false;
}

if (version != UE_ARCHIVE_VERSION)
{
    printf("INVALID VERSION");
    return false;
}

archive->Header = UE_ArchiveHeader();

archive->Header.signature = Header;
archive->Header.version = version;

while(input.is_open())
{

    auto F = make_unique<UE_ArchiveFile>();

    auto Name = std::make_unique<char>();

    input.read(Name.get(), 128);

    F->name = Name.get();

    input.read(reinterpret_cast<char*>(&F->size), sizeof(long));
    if (F->size < 0)
        break;

    char * buffer = new char[F->size];

    input.read(buffer, F->size);
    F->buffer = buffer;

    if (input.fail())
    {
        break;
    }
    else

        archive->Files.push_back(move(F));

}

input.close();
return true;
}

有时这个函数在没有自动触发断点的情况下运行,但如果它有效,那么在使用此函数几秒后,程序将在空闲时随机中断。其他时候它停在最后一行。我无法弄清楚出现这么多不一致的情况,我知道我在这里做了一些事情来打破这个程序。

1 个答案:

答案 0 :(得分:1)

很可能是由于您使用/** * @param int w : length of the formatted string (e.g. 30) * @param String s : the string to be formatted * @param char c : character to pad with * @param boolean pr: If s is odd, pad one extra left or right * @return the original string, with pad 'p' on both sides */ private String pad(String s, int w, char c, boolean pr){ int pad = w-s.length(); String p = ""; for (int i=0; i<pad/2; i++) p = p + c; /* If s.length is odd */ if (pad%2 == 1) /* Pad one extra either right or left */ if (pr) s = s + c; else s = c + s; return (p+s+p) } 的方式。

首先动态分配三个字节。然后你读三个字节。没关系。然后将其分配给字符串。不行没有终止nul,因此它将继续读取内存,直到找到一个并导致未定义的行为。

整件事情一团糟。你为什么要经历这个字符串?你清楚地意识到了一些错误,并试图解决它。

由于您没有释放分配,您也会泄漏内存。

为什么不直接分配一个四字节数组,读取三个字节并将第四个设置为nul?然后你不需要整个字符串kludge,可能不会有随机崩溃。

此外,由于Header在外面使用,您还有另一个问题:您正在存储对方法完成后将被销毁的本地对象的引用,从而导致更多问题。

并且在早退的情况下释放内存。