Solved

Difference between array name and array address ?

Posted on 2013-10-29
11
291 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
 

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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

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
 

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
 

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

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…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
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 clear a vector as well as how to detect empty vectors in C++.

911 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now