Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - Problems stepping through a struct pointer

This is fairly elementary and I'm probably missing something really obvious, but this one has me a bit stumped. Basically, let's say I'm trying to turn an entire PPM image red (that's not actually what I'm doing, but for the sake of troubleshooting, we'll go with that). I have a struct that I'm using to store the pixel values in.

typedef struct pixel_type
{
   unsigned char r;
   unsigned char g;
   unsigned char b;
}  pixel_t;

The pointer that I am using to point to that struct is "buffer."

pixel_t *buffer;

Which I have also allocated the amount of space I need for (the width of the image * the height of the image * the number of pixel values [3] )

buffer = malloc(WIDTH*HEIGHT*sizeof(pixel_t));

I then have a 'for' loop which I am using to step through the buffer pointer and convert every pixel value to red.

int i;
for (i=0;i<(WIDTH*HEIGHT);i++){
   buffer->r=255;
   buffer->g=0;
   buffer->b=0;
   buffer++;} //this part appears to be the problem

The problem here is the output is just a black image with a few garbage pixels right at the top. I have also tried taking out the 'buffer++," and the first pixel appears to be converted to red with no issues. However, when I put it back in, NONE of the pixels are red (not even the first one).

I am not sure what I'm missing. I know that when you create a pointer, you can step through to the next address of the pointer simply by doing the pointer (without a * dereference) with a '++' at the end. Nevertheless, this seems to be the issue. Can someone tell me what I'm doing wrong?

Thanks again,

Austin

like image 639
Austin Avatar asked Sep 09 '13 01:09

Austin


2 Answers

I think the problem is that you are not storing the initial value of the buffer pointer that you have allocated. You increment the pointer in a loop as you go, so buffer points to the end of the buffer after the loop is over.

Use a different pointer in your loop to fix this problem:

int i;
pixel_t *ptr;
for (i=0, ptr = buffer;i<(WIDTH*HEIGHT);i++){
   ptr->r=255;
   ptr->g=0;
   ptr->b=0;
   ptr++;}
like image 197
Sergey Kalinichenko Avatar answered Sep 22 '22 13:09

Sergey Kalinichenko


The first concept to realize is that buffer is a pointer to the storage for your array of pixels. It is the ONLY pointer to that storage. If code modifies buffer then that start of that storage is no longer easily accessed.

Secondly, you want to keep buffer set at its original value so that malloc can be reversed. Thus, keep two pointers to access the array of pixels. One of them is the "anchor" the other the indexer:

   pixel_t  *buffer, *pix;

   buffer = malloc(WIDTH*HEIGHT*sizeof(pixel_t));

   for (pix = buffer; pix < buffer + (WIDTH*HEIGHT); pix++)
   {
     pix->r = 255;
     pix->g = 0;
     pix->b = 0;
   }

   // later in your code
   free(buffer);

So, try this.

like image 29
JackCColeman Avatar answered Sep 25 '22 13:09

JackCColeman