2016-11-11 91 views
2

處理一些使用矩陣的C代碼。我已經創建了一個Matrix結構,以便更快更高效地創建它的許多實例,但我不確定爲什麼我的代碼正在泄漏內存。目前我有以下代碼:無效的寫入/讀取大小爲8

typedef struct 
    { 
    size_t rows; 
    size_t cols; 
    double ** value; 
      } 
    *Matrix; 


Matrix matCreate(size_t rows, size_t cols) 
{ 
     if(rows<=0 || cols<=0) 
     { 
       return NULL; 
     } 
     Matrix mat = (Matrix) malloc(sizeof(Matrix)); 
     mat->rows = rows; 
     mat->cols = cols; 
     mat->value = (double **) malloc(rows*sizeof(double*)); 
     for (int i=0; i< rows;i++) 
     { 
       mat->value[i] = (double *) malloc(cols * sizeof(double)); 
       for(int j=0; j< cols;j++) 
       { 
         mat->value[i][j] = 0; 

         if(rows == cols && i==j) 
         { 
           mat->value[i][j] = 1; 
         } 
       } 

     } 
     return mat; 
} 

而且我運行valgrind後出現以下內存泄漏。運行代碼時,它完全無錯地編譯,並仍然輸出正確的輸出。

==23609== Invalid write of size 8 
==23609== at 0x400800: matCreate 
==23609== by 0x4010E2: main 
==23609== Address 0x5203048 is 0 bytes after a block of size 8 alloc'd 
==23609== at 0x4C2DB8F: malloc 
==23609== by 0x4007E8: matCreate 
==23609== by 0x4010E2: main 
==23609== 
==23609== Invalid write of size 8 
==23609== at 0x40081B: matCreate 
==23609== by 0x4010E2: main 
==23609== Address 0x5203050 is 8 bytes after a block of size 8 alloc'd 
==23609== at 0x4C2DB8F: 
==23609== by 0x4007E8: matCreate 
==23609== by 0x4010E2: main 
==23609== 
==23609== Invalid read of size 8 
==23609== at 0x40082F: matCreate 
==23609== by 0x4010E2: main 
==23609== Address 0x5203050 is 8 bytes after a block of size 8 alloc'd 
==23609== at 0x4C2DB8F: malloc 
==23609== by 0x4007E8: matCreate 
==23609== by 0x4010E2: main 
+0

嘗試使用'-g'進行編譯,所以'valgrind'會向您顯示訪問發生的確切路線...... – BadZen

+0

您的代碼中沒有矩陣(又名二維數組)。指針不是數組!如果你需要矩陣使用二維數組。一般不要將'malloc'和朋友或'void *'結果。 – Olaf

+0

學習以下內存分配習語:'T p = malloc(sizeof * p)'或'T p = malloc(N * sizeof * p)',其中'T'是一些指針類型。即'sizeof'下沒有類型名稱,也沒有投射'malloc'的結果。這樣可以避免你在這樣的失誤中遇到困難。 – AnT

回答

3

Matrix mat = (Matrix) malloc(sizeof(Matrix)); 

不好。它沒有分配足夠的內存。因此,您的程序具有未定義的行爲。

size(Memory)評估指針的大小,而不是struct的大小。

它需要:

Matrix mat = malloc(sizeof(*mat)); 

定義Matrix這確實是一個指針沒有良好的編碼習慣。這會導致混亂。我建議將其定義爲:

typedef struct 
{ 
    size_t rows; 
    size_t cols; 
    double ** value; 
} Matrix; 

,然後使用:

Matrix* matCreate(size_t rows, size_t cols) { ... } 

... 

Matrix* mat = malloc(sizeof(*mat)); 

Do I cast the result of malloc?

+0

當我的代碼更改爲「矩陣mat =(矩陣)malloc(sizeof(*矩陣))」我得到錯誤:預計表達矩陣之前矩陣mat =(矩陣)malloc(sizeof(*矩陣)); – WasabiCannon

+1

'sizeof(* Matrix)'無效。 「矩陣」是一種類型。你不能在C中「推」「一個類型。你不能通過應用'*'運算符來將指針類型轉換爲pontee類型。 C中沒有這樣的功能,但它可能看起來很合邏輯。 – AnT

+0

你的答案的第二部分也有錯別字。由於您將'Matrix'重新定義爲結構類型(而不是原始指針類型),因此您應用於'malloc'結果的類型應該是'(Matrix *)',而不是'(Matrix)'。當然,一個更好的主意根本不會被拋棄。 – AnT

0

變化

Matrix mat = (Matrix) malloc(sizeof(Matrix)); 

Matrix mat = (Matrix) malloc(sizeof(*Matrix)); 

deference the pointer。現在,您正在爲您的矩陣分配足夠的空間用於指針,而不是對象本身。

+0

'sizeof(* Matrix)'無效。 「矩陣」是一種類型,而不是指針。你不能「尊重」C中的一個類型。 – AnT