2016-05-29 94 views
0

所以我寫了一個矩陣,其中包含一個結構像素。該代碼似乎將標準像素寫入矩陣,但是當我嘗試打印出內容時,它似乎指向了錯誤的地址,因爲AddressSanitizer即將出現,即printf正在從錯誤地址讀取: 這裏是該代碼與測試的printf()分配:從矩陣讀取,分配malloc,AddressSanitizer:堆緩衝區溢出

#include <stdio.h> 
#include <stdlib.h> 
#include "matrx.h" 
#include "pixel.h" 

void matr_initializer(struct matrix* matr, int w, int h){ 

matr->height = h; 
matr->width = w; 
struct pixel p; 
standardPixel(&p); 
matr->grid = (struct pixel**)malloc(sizeof(struct pixel)*w); 

if(matr->grid == NULL){ 
    fprintf(stderr,"Irgendwas lief beim allozieren verkehrt"); 
    abort(); 
} 

for(int i = 0; i < w; i++){ 
    matr->grid[i] = (struct pixel*)malloc(sizeof(matr->grid)*h); 
} 

for(int i = 0; i < w; i++){ 
    for(int j = 0; j < h; j++){ 
    matr->grid[i][j] = p; 
    /*Here is the printf that causes the error*/ 
    printf("%d %d %d ",matr->grid[i][j].r,matr->grid[i][j].g,matr->grid[i][j].b); 
} 
    printf("\n"); 
} 


matr->n = w*h; 
matr->init = 1; 

} 

這裏是頭文件我使用:

#ifndef _MATRH_ 
#define _MATRH_ 
#include <stdio.h> 
#include <stdlib.h> 
#include "pixel.h" 
// typedef struct matrix matrix; 

struct matrix{ 
int height; 
int width; 
struct pixel* spalten; 
struct pixel** grid; 
int n; 
int init; 
}; 

void matr_initializer(struct matrix* matr, int w, int h); 


void printf_matr_color(struct matrix* matr); 

void printf_matr_RGB(struct matrix* matr); 
#endif 

而且pixel.h

#ifndef _PIXELH_ 
#define _PIXELH_ 
#include <stdio.h> 
#include <stdlib.h> 

struct pixel{ 
    int color; 
    int r,g,b; 
    int brightness; 
    int energy; 
}; 

void standardPixel(struct pixel* p); 
#endif 
+0

理想情況下,這可以通過使用gdb來解決。但是你可以通過做'matr-> grid =(struct pixel *)malloc(sizeof(struct pixel)* w * h);''來讓你的生活更輕鬆。你認爲'sizeof(matr-> grid)* h'的作用是什麼? – James

+0

這是真的,我已經想過,但現在好奇,爲什麼這是行不通的,它似乎沒有任何問題 –

回答

0

會員gridstruct matrix被聲明爲struct pixel **,您似乎打算將其用作動態分配數組的指針動態分配數組。這可以。

您爲matr->grid本身的分配本身很奇怪,儘管本身並不成問題。您爲struct pixelw實例分配了足夠的空間,但您實際打算在那裏存儲的是w指針struct pixel。分配的空間足夠大,只要struct pixel至少與struct pixel *一樣大,但是您確實應該通過分配足夠大的空間來避免所有的疑問,而且這並不是過分的。

您對成員指針matr->grid指向的空間的分配是更嚴重的問題出現的地方。對於您分配sizeof(matr->grid)*h字節的每個字節,但您似乎實際需要的是sizeof(struct pixel) * h個字節。很有可能struct pixel大於matr->grid(a struct pixel **),在這種情況下,您沒有根據需要分配儘可能多的內存。

這似乎是你真正想要的:

matr->grid = malloc(sizeof(*matr->grid) * w); 
for(int i = 0; i < w; i++){ 
    matr->grid[i] = malloc(sizeof(*matr->grid[i]) * h); 
} 
/* error checking omitted for brevity */ 

東西這裏要注意:

  • 沒有必要,一般不希望投用C
  • malloc()返回值
  • 運算符sizeof不評估其操作數;它只使用操作數類型(有一個例外,這裏不適用)。
  • 因此,正如所證明的那樣,根據指針引用的大小計算分配的字節數是有效的。這可確保您使用正確的元素大小,即使您更改指針的類型。

此外,請注意,雖然您的索引似乎與您的分配和尺寸標註一致,但您的網格編制方式與[column][row]相同。相反,安排索引[row][column]更爲典型。

+0

謝謝!有一天我在stackoverflow上找到了我爲矩陣分配問題的答案,因爲我的導師告訴我一個錯誤的分配,長話短說,你是先生,是我的英雄! –