1

I was looking through some code, and I stumbled upon this line of code. (With other lines of code to provide context)

void write32le(int in, unsigned char * buf) {
    buf[0]=in&0xff;
    buf[1]=(in>>8)&0xff;
    buf[2]=(in>>16)&0xff;
    buf[3]=(in>>24)&0xff;
}

.......

unsigned char wavhead[44] = {
    0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00,  0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20,
    0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x02, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61,  0x00, 0x00, 0x00, 0x00
    };

.......

write32le(outsizetotal,wavhead+4);

The last two lines pieces of code are in the same function if that makes a difference, and the question I have is in the last line. "wavhead+4", what exactly is it doing? Appending the number 4 to 'wavhead'?

5 Answers 5

4

No, it passes the address of (the pointer to) the 5th element of the array (which has index 4, as indexes starts from zero).

You need to learn pointers and arrays. In C you can't add or remove elements from the array

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

Comments

1

Arrays are a continuous block of memory accessed by an address (the location of element 0) and an offset.

wavehead+4 evaluates to the address of the 5th element in the array. The method it's passed into (write32le) will see the 5th element of the array as the 1st element.

// If we take an array
int myArr[] = { 1, 2, 3, 4, 5, 6 }
// And pass it into a method as
myMethod(myArr+2);
// the method will see (assuming it knows the length of the array which it won't in c)
{ 3, 4, 5, 6 }

Comments

1

The purpose of write32le() is to take a word that you wish to re-write as its first argument, and an index into to an array of unsigned int in the form of of a pointer. wavhead[index] is that kind of pointer.

If you wanted to replace the first 4 bytes of wavhead with the word 0xDEADBEEF, you would do this:

int main()
{
    int in=0xDEADBEEF;
    printf("Before write32le:\n ");
    for(int i=0; i<=3; i++)
    {
        printf("0x%hhx ", wavhead[i]);
    }
    printf("\n");

    write32le(in, wavhead);
    printf("After write32le:\n ");
    for(int i=0; i<=3; i++)
    {
        printf("0x%hhx ", wavhead[i]);
    }
    printf("\n");

    return 0;
}

Output:

Before write32le:
 0x52 0x49 0x46 0x46
After write32le:
 0xef 0xbe 0xad 0xde

Comments

0

In majority of contexts (with only a few exceptions) an object of type "array" is implicitly converted to a value of type "pointer". The pointer points to the first element of the array. E.g. in such contexts plain wavhead is implicitly interpreted as &wavhead[0].

In your case wavhead is used as an operand of binary + operator. Binary + is not an exception. So, wavhead decays to &wavhead[0] and your call is interpreted as

write32le(outsizetotal, &wavhead[0] + 4);

which means that what you really have here is "pointer + value", not "array + value".

The second argument results in a pointer to wavhead[4]. You could also rewrite it as

write32le(outsizetotal, &wavhead[4]);

Comments

0

in this case, the name of the array wavhead[] is equal to a pointer of "unsigned char *", adding 4 to this pointer is just moving the pointer by 4 steps and the step is sizeof (unsigned char), which is 1. So wavhead+4 = the address of pointer wavhead + 4, and it points to wavhead[4] after the addition.

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.