Thread: strange number problem

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    7

    strange number problem

    Hi I just started C and since I started with a scripting language, pointers are hard to grasp.
    I'm hoping someone can help me with this baffling problem.
    I wrote the code below hoping to make a image manipulating program. I create a white image and output it as ppm type 3 format but I get a strange result.

    Code:
    #include <stdio.h>
    #include <stdarg.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
    
    
    typedef struct pixel {
    	float r, g, b;
    } pixel;
    
    typedef struct image {
    	int		width, height;
    	pixel	*(data[]);
    } image;
    
    void createWhiteImage(image **img, int width, int height) {
    	int i;
    	pixel pixels[width*height];
    	for(i = 0; i < width*height; ++i)
    	{
    		pixels[i].r = 255;
    		pixels[i].g = 255;
    		pixels[i].b = 255;
    	}
    	*img = (image *)malloc(sizeof(image));
    	(**img).width = width;
    	(**img).height = height;
    	(*((**img).data)) = pixels;
    }
    
    void imageToP3(char *str, image *img) {
    	int i;
    	char tmp[70];
    	strcpy(str, "P3\n");
    	sprintf(tmp, "%d %d\n", img->width, img->height);
    	strcat(str, tmp);
    	strcat(str, "255\n");
    	for(i = 0; i < img->width*img->height; ++i)
    	{
    		sprintf(tmp, "% 3.0f % 3.0f % 3.0f  ", (*(img->data))[i].r, (*(img->data))[i].g, (*(img->data))[i].b);
    		strcat(str, tmp);
    		if ( i%10 ==9 ) {
    			strcat(str, "\n");
    		}
    	}
    }
    
    pixel getPixel(image *img, int x, int y) {
    	return (*((*img).data))[img->width * y + x - 1];
    }
    
    int main (int argc, char const *argv[])
    {
    	image *b;
    	char str[10000];
    	createWhiteImage(&b, 10, 10);
    	imageToP3(str, b);
    	printf("%s\n", str);
    	return 0;
    }
    Result:
    Code:
    P3
    10 10
    255
     255  255  255   255  255  255   255  255  255   255  255  255   255  255  255   255  255  255   255  255  255   255  255  255   255  255  255   255  255  255  
     255  255  255   255  255  255   255  255  255   255  255  255   255  255  -2   255  255  255   255  255  255   255  255  255   255  255  255   255  255  255  
     255  255  255   255  255  255   255  255  255   255  255  255   255  255  255   255  255  255   255  255  -2   255  255  255   255  255  255   255  255  255  
     255  255   0   -2   0   0   -2   0  -0   -0  -2   0   -0  255  255   255  255  255   255  255  255   255  -2  255   255  255  255   255  255   0  
      0   0   0    0  -2   0    0   0  -2   -2  -0   0    0   0   0   -0   0  2422584382005669456248832   -0  255  255   -0  -0   0    0   0   0    0   0   0  
      0   0   0    0   0   0    0   0  -2    0  -2  -2    0  -0  -2    0  -0   0   -2  -0  -0   -0   0   0   -0   0   0    0  -2   0  
      0   0   0    0   0   0    0   0   0    0  -2  -0  nan   0  -2  nan  -0   0    0   0   0   -0  255  255   -2  255   0   -0   0   0  
      0  -0   0    0   0   0    0   0   0    0   0   0    0   0   0    0   0   0    0   0   0    0   0   0    0   0   0    0   0   0  
      0   0   0    0   0   0    0   0   0    0   0   0    0   0   0    0   0   0    0  255  255   255  255  255   255  255  255    0   0  -2  
     -2   0  -2   255   0  255   255  255  -2    0   4   0    2   0   0    0   0   0    0   0   0    0   0   0    0   0   0   255  255  255
    Why do I get these strange numbers? What am I doing wrong?
    Environment: Mac OS X, PPC

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    > pixel pixels[width*height];
    Since this array is local to function createWhiteImage, it ceases to exist once the function ends. And you're storing this address of this local array in img.

  3. #3
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    You might want to try using a library that allows you to display some proper visual output. SDL might be a good one to start with. Lodes computer graphics tutorials explains a lot of the stuff you might want to do as well.

    For storing colours you would probably be better using an integer RGB value than 3 floats. It would save a lot of space.

  4. #4
    Registered User
    Join Date
    Aug 2007
    Posts
    7
    Thanks swoopy! So my guess is that I could use malloc to allocate sizeof(pixel)*width*height bytes of memory, but then I would have to manually move the pointer sizeof(pixel) at a time. Is this ok or is there a better proper way?

    Thanks mike_g! Right now I'm only writing this to learn more about C but SDL will be great to use in the future.

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >So my guess is that I could use malloc to allocate sizeof(pixel)*width*height bytes of memory,
    Correct. And ideally the memory should be freed at the end of main().
    >but then I would have to manually move the pointer sizeof(pixel) at a time.
    Actually since it's be declared of type pixel, you could use array index notation like you are doing now on your pixels array. Even if you decided to use a pointer versus a simple array index, the pointer would increment automatically by sizeof(pixel). But why not use array indexing?

    By the way some of your notation can be simplified, for example:
    Code:
    	(**img).width = width;
    	(**img).height = height;
    This could be rewritten as:
    Code:
    	(*img)->width = width;
    	(*img)->height = height;

  6. #6
    Registered User
    Join Date
    Aug 2007
    Posts
    7
    Thanks for your advice swoopy! I've managed to write a working script that reads and writes p3 files. thanks alot!

  7. #7
    Registered User
    Join Date
    Aug 2007
    Posts
    7
    Actually I have one more question...
    I don't know how to free memory.
    This is my code
    Code:
    typedef struct pixel {
    	int r, g, b;
    } pixel;
    
    typedef struct image {
    	int		width, height;
    	pixel	*data;
    } image;
    
    void createWhiteImage(image **img, int width, int height)
    {
    	int i;
    	*img = (image *)malloc(sizeof(image));
    	(*img)->data = malloc(sizeof(pixel)*width*height);
    	for(i = 0; i < width*height; ++i)
    	{
    		((*img)->data)[i].r = 255;
    		((*img)->data)[i].g = 255;
    		((*img)->data)[i].b = 255;
    	}
    	(*img)->width = width;
    	(*img)->height = height;
    }
    and I wrote a function that will free the memory
    Code:
    void freeImage(image **img)
    {
    	free((*img)->data);
    	free((*img));
    }
    Am I doing enough freeing? I always get confused about what to free.

  8. #8
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Yes you do enough freeing
    What you can add to your function - setting *img pointer to NULL to prevent using the freeed memory by mistake
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    See the FAQ on casting malloc in C programs (don't do it).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Aug 2007
    Posts
    7
    thanks vart and Salem. I've followed both advices and successfully implemented in my code. I was casting malloc without thinking so it was very interesting read.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strange problem
    By G4B3 in forum C Programming
    Replies: 6
    Last Post: 05-14-2008, 02:07 PM
  2. Strange problem with classes in header files
    By samGwilliam in forum C++ Programming
    Replies: 2
    Last Post: 02-29-2008, 04:55 AM
  3. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  4. Interesting number theory problem
    By Zach L. in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 09-20-2003, 07:45 AM
  5. Perfect Number Problem
    By TrazPFloyd in forum C++ Programming
    Replies: 21
    Last Post: 10-20-2002, 11:09 AM