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?

4
  • The link is not working for me. It just says "Forbidden" Commented Nov 25, 2017 at 20:47
  • @NullDev try now? It was set to private by default. Commented Nov 25, 2017 at 20:48
  • Yes, it works now :) Commented Nov 25, 2017 at 20:49
  • 4
    Operator precedence. You should do (*b)[0] = 0x12. This makes this question not related to the actual problem, and the problem is close to being a typo. Question should probably be closed/removed. Commented Nov 25, 2017 at 20:49

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Don't put a space between the dereference operator and the pointer
Just like you shouldn't put a space between an object and an increment/decrement operator (leading/trailing).
@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.
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;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.