Solved

Difference between array name and array address ?

Posted on 2013-10-29
11
324 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 34

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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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 34

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 34

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

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

691 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