简体   繁体   中英

reading from a matrix, allocated with malloc, AddressSanitizer: heap-buffer-overflow

So i'm writing a matrix which contains a struct pixel. The code seems to write the standard pixel into the matrix, but when i try to print out the content, it seems to point to a wrong address, because the AddressSanitizer is coming up, that printf is reading from a wrong address: Here is the code that for allocating with the test printf():

#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;

}

Here is are the header files i'm using:

 #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

And the 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

Member grid of struct matrix is declared as a struct pixel ** , and you appear intent on using it as a dynamically-allocated array of pointers to dynamically-allocated arrays. This is fine.

Your allocation for matr->grid itself is odd, albeit not problematic in itself. You allocate space sufficient for w instances of struct pixel , but what you actually intend to store there are w pointers to struct pixel . The allocated space is large enough as long as a struct pixel is at least as large as a struct pixel * , but you really ought to avoid all doubt by allocating space that is assured to be of sufficient size, and that furthermore is not excessive.

Your allocations for the space pointed to by the member pointers matr->grid is where the more serious problem appears to lie. For each one you allocate sizeof(matr->grid)*h bytes, but what you seem actually to want is sizeof(struct pixel) * h bytes. Very likely a struct pixel is larger than matr->grid (a struct pixel ** ), in which case you are not allocating as much memory as you need.

This appears to be what you really want:

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 */

Things to note here:

  • It is not necessary and generally not desirable to cast the return value of malloc() in C
  • The sizeof operator does not evaluate its operand; it uses only the operand's type (with one exception that does not apply here).
  • It is therefore valid to compute the number of bytes to allocate in terms of the size of the pointer's referrent, as demonstrated. This ensures that you use the correct element size, even if you change the type of the pointer.

Additionally, be aware that although your indexing appears to be consistent with your allocation and dimensioning, the way you've done it, your grid is indexed by [column][row] . It is much more typical to arrange to index by [row][column] , instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM