Reputation: 5132
I'm facing a weird behavior. My C knowledge isn't enough to understand what's happening.
I'm using TI's C compiler (for CC3220SF) in Code Composer Studio. As I did usually I wrote this function:
unsigned char rxBuf[512];
void ReadID(unsigned char device[])
{
// this function reads 2 bytes and put them into
// the global buffer rxBuf;
FlashMemory_Read(ID_ADDRESS, 2);
device = &rxBuf[0];
}
(Note: here I don't pass the length because it's fixed to 2 by design).
Here how I use it:
unsigned char device[2];
ReadID(device);
as pointed out from many answers the compiler treats in the same way a parameter declared as * or [], and its value is the address (pointer) to the first element.
Two unexpected behaviors:
What is wrong here, and why?
The expected behavior is the device variable should point to rxBuf even when ReadID ends, because the pointer has set to the address of rxBuf. Instead it seems the address is changed only locally!
Upvotes: 1
Views: 1095
Reputation: 5591
I think all the people who has answered your question could not understood your small question. You are asking as array
in c
behave/act like a pointer why your below line of code is not working?
device = &rxBuf[0];//as you assigning the address of first character to
//your `device array` its not going to work as device is just a character array and not array pointer
it should be like below
*device = rxBuf[0];
To copy more than one character you can use a for loop like below.
int i;
for(i=0; i<3; i++){
*(device + i) = rxBuf[i];
}
Upvotes: 2
Reputation: 311108
the compiler warns me that in the ReadID function the 'device' variable was declared but never referenced
The value of the parameter device
is not used in the function, Thus the parameter does not make sense.
Take into account that function parameters are its local variables.
debugging the code, I noticed that inside the ReadID function the device bytes point to the rxBuf values, but in the function that calls ReadID() they read always 0.
What you are trying to do is to change an array but arrays are not modifiable lvalues. When a variable of an array type is declared it can not change its type and denote a different array.
In this call
unsigned char device[2];
ReadID(device);
the expression used as argument is converted to an rvalue that has the type unsigned char *
and points to the first element of the array device
.
You can imagine the function and its call the following way. For clarity I changed the parameter name to distinguish the argument and the parameter
unsigned char device[2];
ReadID(device);
//...
void ReadID( /* unsigned char device[] */ )
{
unsigned char local_device = device;
// this function reads 2 bytes and put them into
// the global buffer rxBuf;
FlashMemory_Read(ID_ADDRESS, 2);
local_device = &rxBuf[0];
}
So what you are trying to do does not make sense.
Instead you could copy the values to the destination array the following way
void ReadID(unsigned char device[])
{
// this function reads 2 bytes and put them into
// the global buffer rxBuf;
FlashMemory_Read(ID_ADDRESS, 2);
memcpy( device, rxBuf, 2 );
}
provided that the array rxBuf
contains two actual data.
Upvotes: 1
Reputation: 782
You are only changing where device points to locally.
What you want to do is something along the line:
void ReadID(unsigned char device[])
{
// this function reads 2 bytes and put them into
// the global buffer rxBuf;
FlashMemory_Read(ID_ADDRESS, 2);
memcpy(device, rxBuf, 2);
}
Also note that rxBuf
and &rxBuf[0]
points to the exact same address in memory.
Upvotes: 1
Reputation: 214920
Your problem is similar to this FAQ: Dynamic memory access only works inside function.
Since the array device[]
decays into unsigned char* device
when passed as parameter, you end up with a pointer device
which is local to that function. Assigning that local copy to point somewhere means it would only last for as long as you are inside the function.
But since what you have in the caller is an array, and not a pointer, this suggests that you have completely misunderstood how arrays and pointers work. Best advice is to re-read those chapters in your C programming book.
What you actually meant to do was probably something like this instead:
void ReadID(unsigned char device[])
{
FlashMemory_Read(ID_ADDRESS, 2);
device[0] = rxBuf[0];
device[1] = rxBuf[1];
}
As a side note, having a global variable of 512 bytes that various functions write to, is horrible program design. Proper design would be to have a function along the lines of this instead:
void FlashMemory_Read(volatile const uint8_t* address,
size_t size,
uint8_t dstbuf[size]);
Upvotes: 3