I get the size of the integer array by using sizeof operator but the problem is:
+ Outside class: It outputs 3 (correct)
+ Inside class: It outputs 1 (incorrect)
So how to fix it?
Thanks

class A
{
	public:
		A(const int a[]);		
};

A::A(const int a[])
{
	cout << "Inside class definition ";
	cout << sizeof(a) / sizeof(int) << endl;
}

int main()
{
	int a[] = {1, 3, 2};	
	A obj(a);
	cout << "Outside class definition ";
	cout << sizeof(a) / sizeof(int) << endl;
        return 0;
}

Recommended Answers

All 8 Replies

how much memory does the following take?
const int a[];
answer: I don't think it is defined. In fact, if declared outside of class that line wouldn't compile because the size of the array needs to be known at compile time, like it is in main(). I'm not sure why it compiles with that line in the class, but then I'm no guru either. I'd change it to something like this:

class A
{
    int a[3];
    A() 
   {
      cout << "Inside class definition ";
      cout << sizeof(a) / sizeof(int) << endl;
    }
};

The business about one array being const int and the other just int confuscates things further.

Inside the class, "a" is really just a pointer variable, which is usually the same size as an int, so that's why you get one.

Outside the class, "a" is a 3-element int array, so that's why you get 3.

Remember that C++ does not automatically know the size of an array that is passed to a function. You would normally pass the size as well.

>how much memory does the following take?
>const int a[];
>answer: I don't think it is defined.
It's quite well defined. You're referring to a function parameter, which (due to the conversion of arrays to pointers) is equivalent to const int *a .

>+ Outside class: It outputs 3 (correct)
>+ Inside class: It outputs 1 (incorrect)
The result is different because the type is different inside and outside of the member function you're calling. In main, the type you give to sizeof is int[3] . In the member function, the type you give to sizeof is int* .

Why is that? Because in just about every case when using arrays, the array name is converted to a pointer to the first element. For example, when you subscript an array (ie. a[2] ), first a is converted to a pointer to the first element, then 2 is added to that pointer, finally, the whole construction is dereferenced to give you the value at a[2] . You may have learned that a[i] is equivalent to *(a + i) . Now you know why.

The problem is that passing an array to a function (or member function) applies this rule but sizeof does not. When you pass an array to a function, the array is converted to a pointer to the first element. When you give an array to sizeof, it doesn't perform any conversion because that wouldn't make sense. What use would sizeof be on arrays if it always evaluated to the size of a pointer? ;)

>So how to fix it?
Unfortunately, the only way to fix it is to store the size where the sizeof trick works, and refer to that stored size when the sizeof trick doesn't. For example:

#include <iostream>

using namespace std;

class A
{
	public:
        A(const int a[], std::size_t n);		
};

A::A(const int a[], std::size_t n)
{
	cout << "Inside class definition ";
	cout << n << endl;
}

int main()
{
	int a[] = {1, 3, 2};	
	A obj(a, sizeof a / sizeof *a);
	cout << "Outside class definition ";
	cout << sizeof(a) / sizeof(int) << endl;
        return 0;
}

It is incorrect to say that a is "converted" to a pointer. a simply is a pointer. That's what an array name is, a constant pointer to the first element.

>It is incorrect to say that a is "converted" to a pointer.
Quite the contrary, my confused friend. It's incorrect to say that an array name "is" a pointer. I'm happy to quote chapter and verse from the C++ standard if you'd like.

>That's what an array name is, a constant pointer to the first element.
You haven't thought this through, have you? If an array name is a constant pointer, how do you explain the behavior of sizeof? If an array name is a constant pointer then there's a lot of voodoo that needs to take place for sizeof to produce the total bytes in an array. On the other hand, if an array name is converted to a pointer only in value context[1], everything falls neatly into place.

Calling an array a pointer is largely harmless as long as you don't try to teach it to others, because there are really only a few cases where an array is not converted to a pointer to the first element. Being wrong in this case generally won't make your code worse in practice. But it makes perfectly sensible concepts seem like magic when you have a fundamental misunderstanding about how things work.

[1] The standard talks about using arrays in value context versus object context, where the conversion applies to value context. The majority of uses are value context, thus the rule nearly always applies.

I see what you mean. Good point.

Initially i guessed i must pass the size of array together with array. But "if i don't ask, i can't sleep" ^^. Anyway, thank all of u, especially clearly Narue's answer.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.