2016-04-07 280 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