-5
typedef struct pixel_type
   {
      unsigned char r;
      unsigned char g;
      unsigned char b;
   }  pixel;     



buffer = (int *) malloc (sizeof(pixel) * stdin );

I keep getting an error that says "invalid operands to binary *(have unsigned int' and 'struct _IO_FILE *)." The struct is defined outside of a function so it is universal. The buffer is defined within the main. I can provide more code if needed. What is my problem?

EDIT: Alright so apparently I was a little confusing. What I'm trying to do is pass a file in, and then malloc enough space for that file. I was thinking of using a FILE function to pass the file in, and then using that, but was hoping to just use "stdin" instead. Is this not allowed? And this is in C. Just tagged C++ hoping someone else might see a similar problem.

Sorry for the silly question. Not new to C as a whole, but new to malloc. Second year student :P

Pete B
  • 81
  • 1
  • 10
  • 2
    That doesn't make any sense at all. Or do you want to get some input from `stdin`? Then you have to read it with e.g. `scanf`. And the casting to `int *`, why do you do that? Don't you want an "array" of `pixel` structures? – Some programmer dude Sep 05 '13 at 17:00
  • why are you passing `stdin`? And, compiler is doing what you told it to do rather than what you expected it to do. – Uchia Itachi Sep 05 '13 at 17:00
  • 3
    What exactly do you expect `stdin` in this case to give you? It is a `FILE`, which represents the keyboard (or terminal, console or whatever you call it). I'm guessing you want to know how big the "input" is, but if that is the case, you will actually have to read it first... – Mats Petersson Sep 05 '13 at 17:00
  • And what do you think this should mean: _`buffer = (int *) malloc (sizeof(pixel) * stdin );`_??? – πάντα ῥεῖ Sep 05 '13 at 17:01
  • -1 for using malloc() in C++. – Hesam Qodsi Sep 05 '13 at 17:03
  • 1
    To get the length of the file, there are a billion posts about that. Here's one: http://stackoverflow.com/questions/238603/how-can-i-get-a-files-size-in-c – lurker Sep 05 '13 at 17:11
  • Not sure if "the length of the file" is the right thing to use here - that highly depends on what the format inside the file actually is - if it's a text file, then size of the file will be much greater than the size of the pixel-data inside it. – Mats Petersson Sep 05 '13 at 17:18
  • Please decide first if you want to use C or C++, these are two different language. Then get you a good book or online resources to read up on that language. Voting to close. – Jens Gustedt Sep 05 '13 at 18:21

2 Answers2

1

I think you want to read the number of pixels from stdin:

int n;
scanf("%d", &n);

and then allocate memory for that many pixels:

unsigned char * buffer = (unsigned char *) malloc (sizeof(pixel) * n );
Paul Evans
  • 27,315
  • 3
  • 37
  • 54
0

The right way to allocate the memory would be something like

size_t elements = 0;

... // get the number of elements as a separate operation

pixel *buffer = malloc( sizeof *buffer * elements ); // note no cast, 
                                                     // operand of sizeof
if ( buffer )
{
   // load your buffer here
}

In C, casting the result of malloc is considered bad practice1. It's unnecessary, since values of void * can be assigned to any pointer type, and under C89 compilers it can suppress a diagnostic if you forget to include stdlib.h or otherwise don't have a declaration for malloc in scope.

Also, since the expression *buffer has type pixel, the expression sizeof *buffer is equivalent to sizeof (pixel). This can save you some maintenance time if the type of buffer ever changes.

How you get the number of elements for your array really depends on your application. The easiest way would be to stick that value at the head of your data file:

size_t elements = 0;
FILE *data = fopen( "pixels.dat", "r" );
if ( !data )
{
  // You will want to add real error handling here.
  exit( 0 );
}

if ( fscanf( data, "%zu", &elements ) != 1 )
{
  // You will want to add real error handling here
  exit( 0 );
}

pixel *buffer = malloc( sizeof *buffer * elements );
if ( buffer )
{
  for ( size_t i = 0; i < elements; i++ )
  {
    if ( fscanf( data, "%hhu %hhu %hhu", // %hhu for unsigned char
                   &buffer[i].r, &buffer[i].g, &buffer[i].b ) != 3 )
    {
      // more real error handling here
      exit( 0 );
    }
  }
}

Naturally, this assumes that your data file is structured as rows of 3 integer values, like

10 20 30
40 50 60

etc.


1. As opposed to C++, where it's required, but if you're writing C++ you should be using the new operator anyway. Yes, you will see thousands of examples that include the cast. You will also see thousands of examples that use void main(). Most C references are simply crap.
John Bode
  • 119,563
  • 19
  • 122
  • 198