2016-04-07 139 views
0

我发现自己处于困境。我有一个应该删除任何动态分配内存的程序,但每当我尝试调用相关方法时,都会出现内存堆损坏。内存泄漏问题

它似乎工作时,我不调用的方法,但后来我可能导致大量的内存泄漏。有谁知道发生了什么事?

的代码如下:

CSVFile.h:

#pragma once 

class InputPattern; 
class OutputPattern; 

class CSVFile 
{ 
private: 
    const int NAME_MAX = 100; 
    char* name; 
    char** buffer; 
    bool loadedFlag; 
    int patternCount; 
    InputPattern** inputs; 
    OutputPattern** outputs; 

    void setLoadedFlagTrue(); 
    void setLoadedFlagFalse(); 
public: 
    CSVFile(); 
    ~CSVFile(); 
    CSVFile(const char*); 

    void setName(const char*); 
    char* getFilename(char*, int); 

    bool getLoadedFlag(); 
    int loadFile(); 

    InputPattern* getInputPattern(int); 
    OutputPattern* getOutputPattern(int); 

    void addInputPattern(InputPattern*); 
    void addOutputPattern(OutputPattern*); 
    void deleteInputPattern(); 
    void deleteOutputPattern(); 

    void printMetaData(); 
    void printPatterns(); 
    void deleteBuffer(); 
}; 

CSVFile.cpp:

#include "CSVFile.h" 
#include "InputPattern.h" 
#include "OutputPattern.h" 
#include <stdio.h> 
#include <string.h> 

void CSVFile::setLoadedFlagTrue() 
{ 
    loadedFlag = true; 
} 

void CSVFile::setLoadedFlagFalse() 
{ 
    loadedFlag = false; 
} 

CSVFile::CSVFile() 
{ 
    name = NULL; 
    buffer = NULL; 
    inputs = NULL; 
    outputs = NULL; 
    patternCount = 0; 

    inputs = new InputPattern*[10]; 
    outputs = new OutputPattern*[10]; 
    buffer = new char*[4]; 

    int i; 
    for (i = 0; i < 10; i++) 
    { 
     inputs[i] = new InputPattern(); 
     outputs[i] = new OutputPattern(); 
     buffer[i] = new char[NAME_MAX]; 
    } 
} 

CSVFile::~CSVFile() 
{ 
    delete name; 
    name = NULL; 
} 

CSVFile::CSVFile(const char * filename) 
{ 
    name = NULL; 
    buffer = NULL; 
    inputs = NULL; 
    outputs = NULL; 
    patternCount = 0; 

    inputs = new InputPattern*[10]; 
    outputs = new OutputPattern*[10]; 

    int i; 
    for (i = 0; i < 10; i++) 
    { 
     inputs[i] = new InputPattern(); 
     outputs[i] = new OutputPattern(); 
    } 

    name = new char[NAME_MAX]; 
    strcpy(name, filename); 
} 

void CSVFile::setName(const char * filename) 
{ 
    name = new char[NAME_MAX]; 
    strcpy(name, filename); 
} 

char* CSVFile::getFilename(char * outBuff, int outBuffSize) 
{ 
    outBuff = new char[outBuffSize + 1]; 
    strncpy(outBuff, name, outBuffSize); 
    return outBuff; 
} 

bool CSVFile::getLoadedFlag() 
{ 
    if (name == NULL) 
    { 
     setLoadedFlagFalse(); 
     return loadedFlag; 
    } 

    if (patternCount == 10) 
     setLoadedFlagTrue(); 
    else 
     setLoadedFlagFalse(); 

    return loadedFlag; 
} 

int CSVFile::loadFile() 
{ 
    FILE* f; 
    if ((f = fopen(name, "r")) == NULL) 
    { 
     printf("File failed to open\n"); 
     return 0; 
    } 

    for (patternCount = 0; patternCount < 4; patternCount++) 
    { 
     fgets(buffer[patternCount], 100, f); 
    } 

    patternCount = 0; 
    /*ask about input interaction; potentially remove these variables afterwards*/ 
    float tIn, rIn, gIn, bIn, tOut, oOut; 

    /*might change this to make it more flexible*/ 
    while (patternCount < 10) 
    { 
     fscanf(f, "%f,%f,%f,%f,%f,%f", &tIn, &rIn, &gIn, &bIn, &tOut, &oOut); 
     printf("%f,%f,%f,%f,%f,%f\n", tIn, rIn, gIn, bIn, tOut, oOut); 

     inputs[patternCount]->setT(tIn); 
     inputs[patternCount]->setR(rIn); 
     inputs[patternCount]->setG(gIn); 
     inputs[patternCount]->setB(bIn); 
     outputs[patternCount]->setT(tOut); 
     outputs[patternCount]->setO(oOut); 

     patternCount++; 
    } 
    fclose(f); 
    return patternCount; 
} 

InputPattern * CSVFile::getInputPattern(int index) 
{ 
    if (index >= 0 && index < 10) 
     return inputs[index]; 
    else 
     return 0; 
} 

OutputPattern * CSVFile::getOutputPattern(int index) 
{ 
    if (index >= 0 && index < 10) 
     return outputs[index]; 
    else 
     return 0; 
} 

void CSVFile::addInputPattern(InputPattern * in) 
{ 
    inputs[patternCount] = in; 
    patternCount++; 
} 

void CSVFile::addOutputPattern(OutputPattern * out) 
{ 
    outputs[patternCount] = out; 
    patternCount++; 
} 

void CSVFile::deleteInputPattern() 
{ 
    int i; 
    for (i = 0; i < patternCount; i++) 
    { 
     delete inputs[i]; 
    } 

    delete inputs; 
    inputs = NULL; 
} 

void CSVFile::deleteOutputPattern() 
{ 
    int i; 
    for (i = 0; i < patternCount; i++) 
    { 
     delete outputs[i]; 
    } 

    delete outputs; 
    outputs = NULL; 
} 

void CSVFile::printMetaData() 
{ 
    int i; 
    for (i = 0; i < 4; i++) 
    { 
     printf("%s", buffer[i]); 
    } 
} 

void CSVFile::printPatterns() 
{ 
    /*to be completed*/ 
    int i; 
    for (i = 0; i < patternCount; i++) 
    { 
     printf("Class number %d\n", i + 1); 

     printf("T in = %f\n", inputs[i]->getT()); 
     printf("R in = %f\n", inputs[i]->getR()); 
     printf("G in = %f\n", inputs[i]->getG()); 
     printf("B in = %f\n", inputs[i]->getB()); 

     printf("T out = %f\n", outputs[i]->getT()); 
     printf("O out = %f\n", outputs[i]->getO()); 
    } 
} 

void CSVFile::deleteBuffer() 
{ 
    int i; 
    for (i = 0; i < patternCount; i++) 
    { 
     delete buffer[i]; 
    } 

    delete buffer; 
    buffer = NULL; 
} 

TestHarness.cpp样本(这是在主函数执行)

bool TestHarness::testCSVFileSetFilepath() /*this works fine*/ 
{ 
    bool testResult = false; 
    CSVFile* test = NULL; 
    test = new CSVFile(); 
    char *testName = NULL; 

    test->setName("test.txt"); 
    testName = test->getFilename(testName, 10); 
    if (strcmp("test.txt", testName) == 0) 
     testResult = true; 

    delete test; 
    delete testName; 
    test = NULL; 
    testName = NULL; 
    return testResult; 
} 

........................... 

bool TestHarness::testCSVFileLoadFile() /*this causes the corruption*/ 
{ 
    bool testResult = false; 
    CSVFile* test = NULL; 
    test = new CSVFile(); 

    test->setName("C:/Users/user/Documents/AssignmentsSem2/ExampleFile.csv"); 
    if (test->loadFile() == 10) 
     testResult = true; 

    test->deleteInputPattern(); 
    test->deleteOutputPattern(); 
    test->deleteBuffer(); /*these three above methods are the ones I'm talking about*/ 
    delete test; 
    test = NULL; 
    return testResult; 

}

+10

不要重新发明轮子。使用'std :: string'和'std :: vector'让他们为你处理所有的内存管理。 – NathanOliver

+2

堆损坏通常发生在您进入删除代码之前。当你处于解除分配代码时,它已经太晚了。使用内存分析器,例如[valgrind](http://valgrind.org/)在它们发生的时刻捕获它们。 – dasblinkenlight

+1

你可以用'4'来创建这些缓冲区:'buffer = new char * [4];'然后你在循环中为它们分配'10'。 – Galik

回答

0

你可以只主要方法外与

#define _CRTDBG_MAP_ALLOC
#include<crtdbg.h>

struct AtExit 
{ 
    ~AtExit() 
    { 
     _CrtDumpMemoryLeaks(); 
    } 
}doAtExit; 

检查内存泄漏。

只要程序结束,它就会运行。它所做的只是显示你是否有内存泄漏。没有帮助实际找到它们。 您可能需要Visual Studio。 This is how it looks when a memory leak is found