Accessing pointer-to-array's index modifies its size

Hi!
I'm making my own Array template class.

This the costructor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template<typename GType>
class GArray
{
   GType* array_type = nullptr;
   int size = 0;

public:
GArray(int _Size)
{
        size = _Size;
	array_type = new GType[size];

        // initialize
	for (int i = 0; i < size; i++)
		array_type[i] = NULL;
}



I have this operator overloading (brackets for reading/writing to an index, equal to assign an array to another)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
        GType& operator[](int Index)
        {
            if (Index >= 0 && Index < size)
                return array_type[Index];
        }

        const GType& operator[](int Index) const
        {
            if (Index >= 0 && Index < size)
                return array_type[Index];
        }

        GArray<GType>& operator=(const GArray<GType>& other)
        {
            size = other.size;

            delete[] array_type;
            array_type = new GType[size];

            for (int i = 0; i < size; i++)
            {
                array_type[i] = other.array_type[i];
            }

            return *this;           
        }


It works if I instance my Array class without pointers http://i.stack.imgur.com/rgfPw.png

But as long as I instance those as pointers-to-GArray, then it happens something strange.
In the myArr[0] = 9, 9 becomes the SIZE of myArr instead of replacing the index 0 with the value 9
http://i.stack.imgur.com/i2fdv.png
Last edited on
If myArr is a pointer doing myArr[i] is equivalent to *(myArr + i).

So doing
 
myArr[0] = 9;
is just the same as writing
 
*myArr = 9;
It doesn't make much sense to assign an integer to the GArray but it will compile because you have a non-explicit constructor that takes an int as argument, so what really happens is this:
 
*myArr = GArray<int>(9);

To assign 9 to the first element in the GArray you need to first dereference the pointer.
 
(*myArr)[0] = 9;
Last edited on
@Peter87 really thanks!

But I want the people using my library to actually receive a sort of error.

I don't want people to do that, I'd like to be able to make myArr[x] = y; ALWAYS work: either if that's a pointer, or if it's not.

How do I achive this?
You can disable the implicit conversion from int to GArray<int> by marking the constructor with explicit.

1
2
3
4
5
6
7
template<typename GType>
class GArray
{
	...
	excplicit GArray(int _Size)
	{
		...


Then it will give you an error if you tried to assign an integer to a GArray<int> by mistake.

1
2
GArray<int> myArr;
myArr = 9; // error 

1
2
3
GArray<int>* myArrPtr = new GArray<int>(3);
myArrPtr[0] = 9; // error
*myArrPtr = 9; // error 


It is not possible to give an error if someone uses array indexing syntax on a pointer because that is perfectly valid for pointers, and nothing you have control over.

1
2
3
4
5
myArrPtr[0] = GArray<int>(9); // Will compile and work perfectly.

myArrPtr[8] = GArray<int>(9); // This will compile, but will not
                              // work correctly because myArrPtr[8]
                              // is not a valid object. 
Last edited on
Really really thanks guy! =)
Topic archived. No new replies allowed.