2016-09-25 14 views
-1
#define _CRT_SECURE_NO_WARNINGS 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    #include <crtdbg.h> 
    #define _CRTDBG_MAP_ALLOC 

    enum { 
     RUNNING = 1 
    }; 

    struct Point { 
     int x, y; 
    }; 

    struct Line { 
     Point start; 
     Point end; 
    }; 

    struct GraphicElement { 
     enum { 
      SIZE = 256 
     }; 
     unsigned int numLines; //number of lines 
     Line * pLines; //plines points to start and end 
     char name[SIZE]; 
    }; 

    typedef struct { 
     unsigned int numGraphicElements; 
     GraphicElement * pElements; //the head points to pLines 
    } 
    VectorGraphic; 

    void InitVectorGraphic(VectorGraphic *); 
    void AddGraphicElement(VectorGraphic *); 
    void CleanUpVectorGraphic(VectorGraphic *); 

    VectorGraphic Image; 

    int main() { 
     char response; 
     InitVectorGraphic(& Image); 

     _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 

     while (RUNNING) { 
      printf("\nPlease select an option:\n"); 
      printf("1. Add a Graphic Element\n"); 
      printf("2. List the Graphic Elements\n"); 
      printf("q. Quit\n"); 
      printf("CHOICE: "); 
      fflush(stdin); 
      scanf("%c", & response); 

      switch (response) { 
       case '1': 
        AddGraphicElement(& Image); 
        break; 
       case '2': 
        ReportVectorGraphic(& Image); 
        break; 
       case 'q': 
        CleanUpVectorGraphic(& Image); 
        return 0; 
       default: 
        printf("Please enter a valid option\n"); 
      } 
      printf("\n"); 
     } 
    } 

    /*initialize the vectors, allocate memory*/ 
    void InitVectorGraphic(VectorGraphic * pImage) { //addres of pImage is passed in 
     pImage - > pElements = (GraphicElement *) malloc(sizeof(GraphicElement)); //pImage is now the addess of image 
     pImage - > numGraphicElements = 0; 
    } 



    /*add values into the vectors list.*/ 
    void AddGraphicElement(VectorGraphic * pImage) { 
     struct GraphicElement * pElements; 
     struct GraphicElement * pSecond; 
     struct Point point; 
     struct Line * line; 
     unsigned int numLines; 
     char name[256]; 
     int x; 
     int y; 
     int i = 0; 
     int count = 0; 

     //allocate memory 
     line = (struct Line *) malloc(20 * sizeof(Line)); //allocate memory for line, in order to accsess Line struct values 


    pElements = (GraphicElement *) malloc(20 * sizeof(GraphicElement)); 
      printf("Please enter the name of the new GraphicElement(<256 characters): "); 
      scanf("%s", name); 
      strcpy(pElements - > name, name); //copy the elements name 

      printf("How many lines are there in the new GraphicElement? "); 
      scanf("%u", & numLines); 
      pElements - > numLines = numLines; //pass the number of lines indicated 
      pImage - > pElements = pElements; //pass the number of lines indicated 



     pImage - > pElements[pImage - > numGraphicElements] = * pElements; //pass the elements into pImage 
     pImage - > numGraphicElements++; //number of elements 

私はqを押して終了します。プログラムは私にメモリリークがあることを示します。 メモリリークが検出されました! ダンプオブジェクト - > {69}通常ブロック、0x00EF9880,264バイト。 データ:私は解放できないメモリリークが1つあります

/*clear everything, no memory leaks*/ 
    void CleanUpVectorGraphic(VectorGraphic * pImage) { 
     /* free all Lines pointers */ 
     for (int i = 0; i < pImage - > pElements - > numLines; i++) { 
      free(pImage - > pElements[i].pLines); 
     } 
     pImage - > pElements - > numLines = 0; 
     pImage - > numGraphicElements = 0; 

     if (pImage != NULL) { 
      free(pImage - > pElements); 
     } 
    } 

完全<> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD オブジェクトのダンプは、基本的に私のプログラムは、要素の要素名のユーザー、および金額を要求します。その後、start(x、y)とend(x、y)のint値を入力します。その後、qを押して終了し、プログラムを終了します。私はこのメモリリークがどこにあるのかわからずにデバッガを踏んだ。私は非常に多くの異なる戦略を試しましたが、私は失敗しました。どのようにしてこのメ​​モリリークを解放できますか?

注:2番目の要素を追加すると、メモリリークも重複します。

+1

最も重要な答えは、「必要がない限り、ユーザーの生ポインタを使用しないでください」です。データを自分自身で管理できるようにする:http://en.cppreference.com/w/cpp/language/raii –

+0

' - >':コンパイルは可能ですか? – BLUEPIXY

+0

@JimVはいそれはコンパイルして実行します。私はビジュアルスタジオでC++コンパイラを使用しています。私のコードをゆっくりとC++のLOLに変換しています。 – Calidreaminn

答えて

-1

あなたが解放しようとGraphicElementにへのポインタがなかれ、使用して間接参照したり、それらを解放する前に生のポインタをチェックするもの

を指していないように見えるメモリブロックのサイズから:

void CleanUpVectorGraphic(VectorGraphic * pImage) { 
    //always check input 
    if(!pImage) { 
     return; 
    } 
    /* free all Lines pointers */ 
    for (int i = 0; i < pImage->pElements->numLines; i++) { 
     if(pImage->pElements && pImage->pElements[i] && pImage->pElements[i].pLines) { 
      free(pImage->pElements[i].pLines); 
     } 
    } 
    pImage->pElements->numLines = 0; 
    pImage->numGraphicElements = 0; 

    if (pImage != NULL) { 
     free(pImage->pElements); 
    } 
} 
+0

私は、if文の中で受け入れられない型変換を得ています。 – Calidreaminn

+0

'pImage - >'は構文エラーです –

関連する問題