Solved

Difference between array name and array address ?

Posted on 2013-10-29
11
306 Views
Last Modified: 2013-10-30
 ParameterResult ParameterString::setValue(const char * val, unsigned short size, bool force);

const char testbuff [ ] = {0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, 0x03, 0x00, 0x05, 0x00, 0x06, 0x00};

supportedServParam->setValue (  (const char * ) &testbuff,  sizeof ( testbuff )  ) ;

Open in new window



Shouldn't we be passing  'testbuff' instead ?  'testbuff' is address of first element of array.  What is '&testbuff' ?
0
Comment
Question by:naseeam
  • 4
  • 4
  • 3
11 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 325 total points
ID: 39609674
You're right, there should be no '&' - actually, that's what requires the '(const char*)' cast, which would not be necessary if only 'testbuf' was used, since '&testbuf' is actually a 'char**'.
0
 
LVL 33

Assisted Solution

by:sarabande
sarabande earned 75 total points
ID: 39609727
the address of the array in memory is equal to the address of the first array element.

you can use this information to distinguish between pointers and arrays (what can be useful if you need to know whether sizeof function is valid to determine the size of the array). note, an array passed to a function as an argument was always turned to a pointer.

in the call above it would be better to have

supportedServParam->setValue (&testbuff[0],  sizeof (testbuff )  ) ;

Open in new window

what also spares the cast and makes clear that a pointer to char was passed rather than the whole array.

Sara
0
 
LVL 86

Expert Comment

by:jkr
ID: 39609737
Would you mind to elaborate why '&testbuf[0]' is better than 'testbuf'? I am really curious now...
0
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 1

Author Comment

by:naseeam
ID: 39609780
From expert responses, I gather that it's correct to pass address of array as long as it is typecasted as follows:

(const char * ) &testbuff

but shouldn't it be as follows ?

(const char * *) &testbuff
0
 
LVL 86

Expert Comment

by:jkr
ID: 39609790
No, that would cause an error, since the method takes a 'const char*' as the 1st argument. Again, if you only use 'testbuf' (as you assumed) no cast is necessary.
0
 
LVL 1

Author Comment

by:naseeam
ID: 39609844
Why is it correct to pass as follows ?

(const char * ) &testbuff

I believe 'testbuff' is pointer constant.  Address of constant doesn't make sense to me.
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 325 total points
ID: 39609864
>>Address of constant doesn't make sense to me.

That's what I'm saying ;o)

Actually, I am surprised that this works at runtime. I however suspect that your compiler places the array alements atr the same address on the stack, so that it works by chance. Why don't you just try

supportedServParam->setValue (  testbuff,  sizeof ( testbuff )  ) ;

Open in new window


and see how it works?
0
 
LVL 1

Author Comment

by:naseeam
ID: 39609946
I tried it.  It works!
supportedServParam -> setValue ( testbuff ,  sizeof (testbuff ) ) ;

Open in new window


In both cases, argument passed from calling function and argument received from called function
is 0xA00073C0.
0
 
LVL 1

Author Closing Comment

by:naseeam
ID: 39609951
Thank you for answering follow up questions and getting to the root of the problem.
0
 
LVL 33

Expert Comment

by:sarabande
ID: 39610902
Would you mind to elaborate why '&testbuf[0]' is better than 'testbuf'? I am really curious now...
there are a few good reasons:

one is that the function argument is declared as char pointer. hence it is good if we pass a pointer to char explicitly rather than an array variable where the compiler does the cast implicitly.

other advantage is the readability. passing the address of the first array element together with the size, makes it clear that we pass the array from begin and how many elements can be accessed by the function. we also would see that we could point to second or n-th element accordingly.

int arr[nmax] = { 0 };
f(&arr[5], nmax -5); 

Open in new window


if you pass arrays always by address of an array element (as I do if i don't use std::vector), then you always are aware that the array turns to a pointer in the called function.

finally, you could use pointers to array elements when an iterator is required:

int arr[] = { 7, 2, 1, 9, 8 };
int n = (int)sizeof(arr)/sizeof(arr[0]);
std::sort(&arr[0], &arr[n]); // sorts the array

Open in new window


when using a std::vector<int> vec for the array, the sort statement would pass vec.begin(), vec.end() which are iterators.

in the sample code you also could pass 'arr' as first argument and the compiler would not complain. but if you look at the second argument you see that it isn't actually a pointer to a valid array element but an address that points beyond the array boundaries. obviously, it is better here that we pass the first argument in the same notation, to make clear that both the arguments have same argument type.

in my opinion, this argument is valid for all cases where an array was passed to a function.

Sara
0
 
LVL 33

Expert Comment

by:sarabande
ID: 39610925
I believe 'testbuff' is pointer constant.  Address of constant doesn't make sense to me.
the const of the first argument has no meaning for the caller but only for the called function (callee). the callee cannot write to the memory the pointer is pointing to when the pointer is declared to be const.

for the cast in the caller, the const has no meaning. it also would work when you omit the const. the cast was casting the address of a char array (&testbuff), what is a pointer to char array, what is equivalent to pointer to char pointer, to a char pointer. generally, pointers can be casted to any other pointer type if you use a reinterpret_cast, what means that the types of the pointers are ignored.

sometype * p1;
anothertype * p2;
p2 = reinterpret_cast<sometype *>(p1);

Open in new window


if 'anothertype' is a pointer type, you have a similar situation as in your code sample. in c++ you also can use c cast where the compiler decides which variant of static_cast, const_cast, dynamic_cast, or reinterpret_cast was used.

sometype * p1;
anothertype * p2;
p2 = (sometype *)(p1);

Open in new window



for pointer casts a c cast is always a reinterpret_cast as long as the pointers are not pointing to class types or functions where the class relation or argument list was considered. so the c cast in your code sample only tells the compiler that it should use the address of the array variable testbuff as a 'const char *'. as this was the required argument type, the compiler neither complains nor does it fail cause the addresses are equal as you have seen in the debugger.

Sara
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

808 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question