2016-05-29 90 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上找到了我为矩阵分配问题的答案,因为我的导师告诉我一个错误的分配,长话短说,你是先生,是我的英雄! –