2

Trying to pass a char array as a parameter of a function but it is not being passed. Specifically, trying to pass the unsigned char array 'p' to function 'setlsbs' (ignore apparent purpose of function. just trying to pass it correctly at the moment).

The code:

#include <stdio.h>
#include <stdlib.h>

#define BYTETOBINARYPATTERN "%d%d%d%d%d%d%d%d"
#define BYTETOBINARY(byte)  \
  (byte & 0x80 ? 1 : 0), \
  (byte & 0x40 ? 1 : 0), \
  (byte & 0x20 ? 1 : 0), \
  (byte & 0x10 ? 1 : 0), \
  (byte & 0x08 ? 1 : 0), \
  (byte & 0x04 ? 1 : 0), \
  (byte & 0x02 ? 1 : 0), \
  (byte & 0x01 ? 1 : 0) 
#define PRINTBIN(x)  printf(BYTETOBINARYPATTERN, BYTETOBINARY(x)); 

void setlsbs(unsigned char* p, unsigned char b0);
unsigned char getlsbs(unsigned char *p);

//MAIN
int main(int argc, char **argv){
   //default seed
   long seed = 1234;

   //if argv[1] available, use it as the seed instead
   if(argv[1]){
      sscanf(argv[1], "%ld", &seed);
   }

   //seed RNG
   srand(seed);

   //make array for eight bytes
   unsigned char *p[8];

   //fill array with random num 0-255
   int cnt;
   for(cnt = 0; cnt<8; cnt++){
      p[cnt] = (unsigned char*)(rand()%255);
      printf("p[%d] decimal:%d and binary:", cnt, p[cnt]);
      PRINTBIN((int)p[cnt]);
      printf("\n");
   }

   //make random num for b0
   unsigned char b0 = (unsigned char)(rand()%255);
   printf("b0 decimal:%d and binary:", b0);
      PRINTBIN((int)b0);
      printf("\n");

   //call setlsbs
   setlsbs((unsigned char*)p, (unsigned char)b0);
}

//SET LSBS
void setlsbs(unsigned char *p, unsigned char b0){
   printf("p[0]: %d\n", p[0]);
}

//GET LSBS
unsigned char getlsbs(unsigned char *p){

}

Results:

p[0] decimal:243 and binary:11110011
p[1] decimal:175 and binary:10101111
p[2] decimal:32 and binary:00100000
p[3] decimal:230 and binary:11100110
p[4] decimal:117 and binary:01110101
p[5] decimal:189 and binary:10111101
p[6] decimal:29 and binary:00011101
p[7] decimal:227 and binary:11100011
b0 decimal:233 and binary:11101001
p[0]: 0

That last line should be p[0]: 243

Thanks!

  • 1
    `//make array for eight bytes` - `unsigned char *p[8]` nope. that's eight *pointers* (though granted it is most-assuredly well-over 8 octets in size). – WhozCraig Nov 13 '14 at 04:39
  • 1
    Did you stop to think for a second why this cast is necessary - `(unsigned char*)(rand()%255)`? Casts aren't something you throw at the compiler until it shuts up. – Praetorian Nov 13 '14 at 04:44
  • 1
    @Praetorian - Thank you. I am still learning a lot about C. I have changed this and will keep it in mind for the future. Thank you. – Matt Jefferson Nov 13 '14 at 04:47
  • this line: unsigned char *p[8]; makes an array of 8 pointers, where the pointers have no specific thing they are pointing to. – user3629249 Nov 13 '14 at 07:15
  • this line: p[cnt] = (unsigned char*)(rand()%255); is setting p[x] to be a pointer to some location within the first 256 bytes of memory. the is probably not what you want, as you have no control over what the byte is in the first 256 bytes of memory. (and reading those bytes could easily result in a seg fault event. suggest char p[8]; and p[cnt] = (rand()%255); and remove all the references to (unsigned char *) from the code. – user3629249 Nov 13 '14 at 07:29

2 Answers2

4

The first warning signal that should concern you is here:

setlsbs((unsigned char*)p, (unsigned char)b0);

Why are you casting? If p is the correct type you won't need to cast. You should write:

setlsbs(p, b0);

Of course, that won't compile because p is the wrong type. But now you are letting the compiler tell you that. Let's look at p:

unsigned char *p[8];

That is an array whose elements are of type unsigned char*. Not what you want at all. You need to declare an array whose elements are of type unsigned char:

unsigned char p[8];

You can then pass p directly to setlsbs and allow it to decay to a pointer.

You will also be able to remove the next dubious cast:

p[cnt] = (unsigned char*)(rand()%255);

You needed that cast to suppress the compilers errors when you had declared p incorrectly. With the declaration above this cast can be removed:

p[cnt] = rand()%255;

Although I suspect that you might actually mean:

p[cnt] = rand()%256;

As you have written it, rand()%255 yields a value in the range [0..254] and can never yield 255.

And then you can change:

PRINTBIN((int)p[cnt]);

to

PRINTBIN(p[cnt]);

and so on.


As a general rule, casts should be avoided. Your question illustrates a classic mistake. The compiler tells you that you made a mistake. You misinterpret the error message as indicating that you need a cast and so add a cast. The cast doesn't fix the mistake, it merely suppresses the compiler error. Now you've got an error that the compiler cannot help you with, and life suddenly gets a whole lot more complicated.

You should aim to make this code free from casts.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
0

In your code unsigned char *p[8]; meaning p is a pointer to array of 8 unsigned char *. when p is passed to function setlsbs() function, unsigned char * at the location 0 of the array is passed! and value for that is not assigned yet. Which will be junk at that moment! In your case it is 0!

If you just want to make array of 8 bytes, try unsigned char p[8]; and then pass pointer p to the function setlsbs() function. then try to print the p[0]. you will get the proper result.

You can check the difference of unsigned char *p[8] and unsigned char (*p)[8] in this link: Difference between *ptr[10] and (*ptr)[10]

I hope this will help you solve the problem.

Community
  • 1
  • 1
Basavaraju B V
  • 174
  • 1
  • 8