2016-04-07 16 views
0

Ich finde mich in einer schwierigen Situation. Ich habe ein Programm, das jeden Speicher löschen soll, der dynamisch zugewiesen wird, aber wenn ich versuche, die relevanten Methoden aufzurufen, kommt es zu einer Speicher-Heap-Beschädigung.Speicherverlust betrifft

Es scheint zu funktionieren, wenn ich die Methoden nicht aufrufen, aber dann habe ich wahrscheinlich eine Menge Speicherlecks verursacht. Hätte jemand eine Ahnung was los ist?

ist der Code unter:

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 Probe (diese in der Hauptfunktion ausgeführt wird)

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

Erfinden Sie das Rad nicht neu. Verwenden Sie 'std :: string' und' std :: vector' und lassen Sie sie die gesamte Speicherverwaltung für Sie übernehmen. – NathanOliver

+2

Heap-Korruption tritt normalerweise auf, bevor Sie in den Löschcode gelangen. Wenn Sie sich im Freigabe-Code befinden, ist es zu spät. Verwenden Sie einen Speicherprofiler wie [valgrind] (http://valgrind.org/), um sie in dem Moment zu erfassen, in dem sie passieren. – dasblinkenlight

+1

Sie machen '4' von diesen:' buffer = new char * [4]; 'und dann ordnen Sie' 10' von ihnen in der Schleife zu. – Galik

Antwort

0

Sie können außerhalb des Hauptverfahrens mit

#define _CRTDBG_MAP_ALLOC
#include<crtdbg.h>

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

nur für Speicherlecks überprüfen.

Dies wird ausgeführt, wenn Ihr Programm endet. Es zeigt nur an, ob Sie ein Speicherleck haben oder nicht. Es hilft nicht, sie tatsächlich zu finden. Möglicherweise benötigen Sie dafür Visual Studio. This is how it looks when a memory leak is found