Pointer VS array pointer

H

howa

// example

#include <iostream>

using namespace std;

size_t bsearch(int *a) {

cout<<a<<endl;
cout<<sizeof(a) / sizeof(a[0])<<endl;

return 1;
}


int main() {

int a[] = {1,3,5,7,9,11};

cout<<a<<endl;
cout<<sizeof(a) / sizeof(a[0])<<endl;;
cout<< bsearch(a);

}


why they are difference ?

a has the same value, but why sizeof(a) / sizeof(a[0]) is difference?







thanks
 
R

Ron Natalie

howa said:
size_t bsearch(int *a) {

a is a pointer to int.
int a[] = {1,3,5,7,9,11};
a is a 6 element array of int.

a has the same value, but why sizeof(a) / sizeof(a[0]) is difference?

No they do not have the same value. Arrays and
pointers are different types.
 
D

Default User

howa said:
// example

#include <iostream>

using namespace std;

size_t bsearch(int *a) {

cout<<a<<endl;
cout<<sizeof(a) / sizeof(a[0])<<endl;

return 1;
}


int main() {

int a[] = {1,3,5,7,9,11};

cout<<a<<endl;
cout<<sizeof(a) / sizeof(a[0])<<endl;;
cout<< bsearch(a);

}


why they are difference ?

The first is a pointer and the second is an array. They are different
things.

In many contexts, the name of an array is converted to a pointer to the
first element. The two major exceptions are when used with the sizeof
operator and the address-of operator (&).



Brian
 
G

Gavin Deane

howa said:
// example

#include <iostream>

using namespace std;

size_t bsearch(int *a) {
Here a is of type pointer-to-int. The fact that the int pointed to
happens to be the first in a series of ints that are stored in an array
in the calling function is irrelevant to the type of a here.
cout<<a<<endl;
This statement calls the operator<< function overloaded for pointers
because a is a pointer.
cout<<sizeof(a) / sizeof(a[0])<<endl;
a is of type pointer-to-int
a[0] is of type int
This statement will output the size of a pointer-to-int divided by the
size of an int, whatever that is in your implementation.
return 1;
}


int main() {

int a[] = {1,3,5,7,9,11};
Here a is an array of 6 ints
cout<<a<<endl;
This statement calls the operator<< function overloaded for pointers
because a decays from an array to a pointer in the context of the call
to the operator<< function. So you see the same result as inside the
bsearch function.
cout<<sizeof(a) / sizeof(a[0])<<endl;;
a has type array-of-6-ints and in the context of a sizeof expression
the array name does _not_ decay to a pointer as it did in the call to
operator<< above. So sizeof a is the size of the whole array, 6 x the
size of int. a[0] is of type int so this statement will output (6 x the
size of an int) divied by the size of an int, i.e. the output will be
6.
cout<< bsearch(a);

}


why they are difference ?

a has the same value, but why sizeof(a) / sizeof(a[0]) is difference?

Because in one case a is an array of six ints and in the other case a
is a pointer and those two entities are not the same size. (In both
cases a[0] is an int so is the same size in each case)

Gavin Deane
 
S

Salt_Peter

howa said:
// example

#include <iostream>

using namespace std;

size_t bsearch(int *a) {

cout<<a<<endl;
cout<<sizeof(a) / sizeof(a[0])<<endl;

return 1;
}


int main() {

int a[] = {1,3,5,7,9,11};

cout<<a<<endl;
cout<<sizeof(a) / sizeof(a[0])<<endl;;
cout<< bsearch(a);

}


why they are difference ?

a has the same value, but why sizeof(a) / sizeof(a[0]) is difference?

a pointer to int is not an array. An array needs to keep a const count
of the number of elements. A pointer to int needs no such thing. In
the old days, nobody thought about the importance of objects, so you
can't pass an array by value, by pointor nor by reference (unless you
wrap an allocated array in an object).

Does that suck? Nope, since a std::vector solves all those problems
(and more).

#include <iostream>
#include <vector>

size_t getsize(std::vector< int >& r_v)
{
return r_v.size();
}

int main()
{
std::vector< int > vn(6);

std::cout << &vn << std::endl;
std::cout << getsize( vn ) << std::endl;
std::cout << vn.size() << std::endl;
return 0;
}

/*
0x7fffee50abf0
6
6
*/
 
B

Bart

Salt_Peter said:
a pointer to int is not an array. An array needs to keep a const count
of the number of elements. A pointer to int needs no such thing. In
the old days, nobody thought about the importance of objects, so you
can't pass an array by value, by pointor nor by reference (unless you
wrap an allocated array in an object).

It's quite possible to pass arrays by reference, but the size has to be
fixed:

void foo(int (&myarray)[10]);

declares a function taking a reference to an array of 10 ints.

Regards,
Bart.
 
D

Default User

Bart said:
Salt_Peter said:
a pointer to int is not an array. An array needs to keep a const
count of the number of elements. A pointer to int needs no such
thing. In the old days, nobody thought about the importance of
objects, so you can't pass an array by value, by pointor nor by
reference (unless you wrap an allocated array in an object).

It's quite possible to pass arrays by reference, but the size has to
be fixed:

void foo(int (&myarray)[10]);

declares a function taking a reference to an array of 10 ints.


Similarly pointers to arrays can be passed:

void foo(int (*myarray)[10]);

This would be called with something like:


int bar[10];

foo(&bar);




Brian
 
S

Salt_Peter

Default said:
Bart said:
Salt_Peter said:
a pointer to int is not an array. An array needs to keep a const
count of the number of elements. A pointer to int needs no such
thing. In the old days, nobody thought about the importance of
objects, so you can't pass an array by value, by pointor nor by
reference (unless you wrap an allocated array in an object).

It's quite possible to pass arrays by reference, but the size has to
be fixed:

void foo(int (&myarray)[10]);

declares a function taking a reference to an array of 10 ints.


Similarly pointers to arrays can be passed:

void foo(int (*myarray)[10]);

This would be called with something like:


int bar[10];

foo(&bar);

Brian

Thanks to both of you. I stand corrected.
This could indeed be useful, though i had to go ahead and screw with
the issue:

I can unsderstand that template deduction is taking place in the
functions below.
The question is: is the following legal for a function template?

#include <iostream>

template< typename T, const size_t Size >
void array_ptr(T (*myarray)[Size])
{
size_t sz = sizeof(*myarray) / sizeof(T);
std::cout << "array size = " << sz;
std::cout << std::endl;
for (size_t i = 0; i < sz; ++i)
{
std::cout << (*myarray) << "\n";
}
}

template< typename T, const size_t Size >
void array_ref(T (&myarray)[Size])
{
size_t sz = sizeof(myarray) / sizeof(T);
std::cout << "array size = " << sz;
std::cout << std::endl;
for (size_t i = 0; i < sz; ++i)
{
std::cout << myarray << "\n";
}
}

int main()
{
int array[] = {0,1,2,3,4};
array_ptr(&array);
array_ref(array);

double narray[] = {0.0,1.1,2.2,3.3};
array_ref(narray);

std::string sarray[] = {"string 0", "string 1", "string 2"};
array_ref(sarray);

return 0;
}

/*
array size = 5
0
1
2
3
4
array size = 5
0
1
2
3
4
array size = 4
0
1.1
2.2
3.3
array size = 3
string 0
string 1
string 2
*/
 
R

red floyd

Salt_Peter said:
I can unsderstand that template deduction is taking place in the
functions below.
The question is: is the following legal for a function template?

#include <iostream>

template< typename T, const size_t Size >
void array_ptr(T (*myarray)[Size])
{
size_t sz = sizeof(*myarray) / sizeof(T);

size_t sz = Size; // but why bother? Just use Size.
std::cout << "array size = " << sz;
std::cout << std::endl;
for (size_t i = 0; i < sz; ++i)
{
std::cout << (*myarray) << "\n";
}
}

template< typename T, const size_t Size >
void array_ref(T (&myarray)[Size])
{
size_t sz = sizeof(myarray) / sizeof(T);


see above
std::cout << "array size = " << sz;
std::cout << std::endl;
for (size_t i = 0; i < sz; ++i)
{
std::cout << myarray << "\n";
}
}
[redacted]
 
S

Salt_Peter

red said:
Salt_Peter said:
I can unsderstand that template deduction is taking place in the
functions below.
The question is: is the following legal for a function template?

#include <iostream>

template< typename T, const size_t Size >
void array_ptr(T (*myarray)[Size])
{
size_t sz = sizeof(*myarray) / sizeof(T);

size_t sz = Size; // but why bother? Just use Size.

yes, why not indeed. Thanks
std::cout << "array size = " << sz;
std::cout << std::endl;
for (size_t i = 0; i < sz; ++i)
{
std::cout << (*myarray) << "\n";
}
}

template< typename T, const size_t Size >
void array_ref(T (&myarray)[Size])
{
size_t sz = sizeof(myarray) / sizeof(T);


see above
std::cout << "array size = " << sz;
std::cout << std::endl;
for (size_t i = 0; i < sz; ++i)
{
std::cout << myarray << "\n";
}
}
[redacted]
 
S

Salt_Peter

red said:
Salt_Peter said:
I can unsderstand that template deduction is taking place in the
functions below.
The question is: is the following legal for a function template?

#include <iostream>

template< typename T, const size_t Size >
void array_ptr(T (*myarray)[Size])
{
size_t sz = sizeof(*myarray) / sizeof(T);

size_t sz = Size; // but why bother? Just use Size.

Yes, of course, you mean use the variable Size directly.
i'm just testing the theory in the above, convincing myself of what
should be obvious.
Its in the loop below that the constant fits the bill perfectly.
Thanks for input, will do
std::cout << "array size = " << sz;
std::cout << std::endl;
for (size_t i = 0; i < sz; ++i)
{
std::cout << (*myarray) << "\n";
}
}

template< typename T, const size_t Size >
void array_ref(T (&myarray)[Size])
{
size_t sz = sizeof(myarray) / sizeof(T);


see above
std::cout << "array size = " << sz;
std::cout << std::endl;
for (size_t i = 0; i < sz; ++i)
{
std::cout << myarray << "\n";
}
}
[redacted]
 
N

Nick Keighley

Salt_Peter wrote:

a pointer to int is not an array. An array needs to keep a const count
of the number of elements.

since when?
A pointer to int needs no such thing. In
the old days, nobody thought about the importance of objects,

I think C had different design goals from C++. That doesn't necessarily

mean it was wrong.

<snip>
 
K

Kai-Uwe Bux

Nick said:
Salt_Peter wrote:



since when?

Since the requirement was introduced that its destructor calls the
destructor for all objects stored. Therefore, you can get the size of an
array when it dies by hijacking the destructor. The compiler, therefore,
will kept track of the size somewhere:

#include <iostream>
#include <new>

struct X {

static
unsigned & count ( void ) {
static unsigned dummy = 0;
return ( dummy );
}

~X ( void ) {
++ count();
}

};

int main ( void ) {
{
{
X array [300];
X::count() = 0;
}
std::cout << X::count() << '\n';
}
{
unsigned size;
while ( std::cin >> size ) {
X* x_ptr = new X [size];
X::count() = 0;
delete [] x_ptr;
std::cout << X::count() << '\n';
}
}
}

echo 16 | a.out
300
16

However:
a) For types with trivial destructor, the compiler can optimize the count
away since it is not used.
b) If the size is known at compile time, the compiler can use that knowledge
instead of keeping a count.


[snip]


Best

Kai-Uwe Bux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top