0

I am facing an issue while creating a Linux module which I have simulated here.

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

void changeBuff(unsigned char ** b)
{
    *b[0] = 0x12;
    *b[1] = 0x34;
}

int main(void) {
    unsigned char * buf = (unsigned char *)malloc(sizeof(unsigned char) * 2);
    buf[0] = 0x55;
    buf[1] = 0xAA;
    printf("%x\t%x\n", buf[0], buf[1]);
    changeBuff(&buf);
    printf("%x\t%x\n", buf[0], buf[1]);
    return 0;
}

Long story short, I am trying to change values of an array inside a function. While the value at the first index gets changed, the same does not happen for the second index. The output of the code above is

55  aa
12  aa

Somewhat similar problems are addressed in other stackoverflow threads (e.g. Changing an array with a function in C?, Pass and change array inside function in C, Changing array inside function in C) but for some reason, even using a pointer to the character array is not working in my case (as can be seen from the output of the code in the ideone link above). What am I doing wrong here?

an4s
  • 161
  • 1
  • 10

2 Answers2

3

The [] operator binds tighter then the *-operator, so change

*b[0] = 0x12;

to

(*b)[0] = 0x12;

Alternatively change

void changeBuff(unsigned char ** b)
{
  *b[0] = 0x12;
  *b[1] = 0x34;
}

to

void changeBuff(unsigned char * b)
{
  b[0] = 0x12;
  b[1] = 0x34;
}

and instead of calling it like this

  changeBuff(&buf);

call it like this

  changeBuff(buf);

Unrelated to your issue:

  • There is no need to cast from/to void-pointers in C.
  • sizeof (char) equals 1 by definition.

So this line

unsigned char * buf = (unsigned char *)malloc(sizeof(unsigned char) * 2);

is equal to this

unsigned char * buf = malloc(2);

A more robust version would be

unsigned char * buf = malloc(2 * sizeof *buf);

which would survive changing the type of where buf points to.

alk
  • 69,737
  • 10
  • 105
  • 255
  • Don't put a space between the dereference operator and the pointer – iBug Nov 26 '17 at 09:07
  • Just like you shouldn't put a space between an object and an increment/decrement operator (leading/trailing). – iBug Nov 26 '17 at 09:10
  • @alk Thanks for the tips. Casting void pointers has become a habit after working in a company that puts a lot of focus on satisfying static code analysers, some of which would complain on this. – an4s Nov 26 '17 at 19:11
1

Because of operator precedence, *b[0] is equivalent to *(b[0]), which is not you want.

Adding a pair of parentheses around *b is a solution:

(*b)[0] = 0x12;
iBug
  • 35,554
  • 7
  • 89
  • 134