copy assignment operator - arrays

Hello, I am learning to create the assignment operator to work with arrays. I have used it before and thought i understood it but now it has come to arrays im struggling to understand a few things about it.

It says that in the body of the assignment operator, I need to release the previous array block but then am i not losing the array I am copying from then? Why am I doing that? Dont I want to have both arrays at the end of the copy?

So after the code below runs, would b no longer exist? and a would hold what b did?
1
2
3
4
5
6
int a[n];
int b[n];

a = b;

what says that?
What you are asking makes no sense (or, better said, you make sense, but what you are asking about is either nonsense or you have misunderstood it) -- its as if you are reading a chunk out of a book that is making its own dynamic arrays (pointers!) which is not what you are showing in the code.

What you have above does not work on C arrays, they can't use the assignment operator.
If they could, it would, presumably, work just like integers:

int a;
int b;
a = b; //b still exists, of course, and still has its value!

it would be unusual to make a custom operator for any type (arrays or not) that self-destructed the right hand side afterwards. VERY unusual.

also, are you asking about std::array or C-style arrays? std::array is a lightweight wrapper for C arrays that DOES support = operator already.
Last edited on
Your example is using plain old arrays. There is no built-in assignment operator for arrays. And if n isn't constant then the code is not proper C++.

It says that in the body of the assignment operator, I need to release the previous array block but then am i not losing the array I am copying from then?

I don't know what "It" is, but it seems to be referring to a user-defined assignment operator for a class in which you would release the previous contents of the object that is being assigned to before copying the contents of the other object to it. (Alternatively you might reuse the allocated memory if it is big enough.) So the object being copied is left unchanged.
Last edited on
User-defined assignment operators can only be written for a class type.

Copy assignment operator: https://eel.is/c++draft/class.copy.assign#1
After a = b, with a normal copy assignment operator, a would become a logical copy of b and b would remain unchanged.


With a move assignment operator, https://eel.is/c++draft/class.copy.assign#3 , the object on the left hand side of the move assignment operator could steal resources from the (temporary) object on the right hand side.
After a = std::move(b), with a normal move assignment, a would hold a copy of b and b would be placed into an unspecified (but safely destructible) state.


I would suggest to use std::array instead of C arrays.
1
2
3
4
5
6
7
8
9
#include <array>

int main()
{
    std::array a = {1,2,3}; // C++17
    std::array b = {4,5,6};

    a = b;
}

No need to woryy about copy or move operators
Last edited on
Below is the code that was shown before talking about the copy assignment, but for some reason the person does not give the code for the assignment operator and just gives basically what i said above. The code was arrays made with pointers, which i didnt show above. Hopefully this code might help clear up what the video is talking about, with releasing the previous array.

Is it because if two arrays were created, they both would point to the same place? so one needs to be released?

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#pragma once
#include <iostream>
#include <ostream>

using std::ostream;

class indexOutOfBoundsException {};

class intArray
{
private:
	int* ptr = nullptr;
	int size = 0;

	bool isValidIndex(int index) const { return (index >= 0) && (index < size); }
public:
	intArray() = default;

	explicit intArray(int size)
	{
		if (size != 0)
		{
			ptr = new int[size] {}; // include {} to initalise elemnts to 0, without {} would give garbage
			this->size = size;
		}
	}
	~intArray()
	{
		delete[] ptr;
		ptr = nullptr;
	}

	intArray(const intArray& obj)
	{
		if (!obj.isEmpty())
		{
			size = obj.size;

			ptr = new int[size] {};

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

	int Size() const { return size; }
	bool isEmpty() const { return (size == 0); }
	int &operator[] (int index) const
	{
		if (!isValidIndex(index))
		{
			throw indexOutOfBoundsException{};
		}
		return ptr[index];
	} 


};


main
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
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <cassert>
#include "intArray.h"

using std::cout;
using std::cin;

ostream& operator<< (ostream &os, const intArray& a)
{
	os << " [ ";
	for (int i = 0; i < a.Size(); i++)
	{
		os << a[i] << ' ';
	}
	os << " ] ";

	return os;
}

int main()
{

	intArray a{ 3 };
	a[0] = 10;
	a[1] = 20;
	a[2] = 30;

	intArray b = a;

	cout << " a = " << a << '\n';
	cout << " b = " << b << '\n';

	b[1] = 100;

	cout << " b = " << b << '\n';

	return 0;
	
}
That code is using a copy constructor not copy assignment ... and the built-in type int is not the user-defined type intArray.

It is rather different from your original post.
1
2
3
That code is using a copy constructor not copy assignment ... and the built-in type int is not the user-defined type intArray.

It is rather different from your original post.


I know, the code that the video gives doesnt include the assignment operator, he doesnt show the code for that, instead just gives a brief overview of basically what I said above. I just posted the code cause i thought it would help with understanding what the person was trying to say about the assignment operator releasing the previous array
The copy assignment op might look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    intArray& operator=(const intArray& other)
    {
        if (this != &other)
        {
            if (size != other.size)
            {
                delete[] ptr;
                ptr = nullptr;
                size = 0;
                if (other.size > 0) ptr = new int[size];
                size = other.size;
            }
            std::copy(other.ptr, other.ptr + size, ptr);
        }
        return *this;
    }

Last edited on
So why am I deleting what ptr is pointing to in line 7? Because isnt that ptr belonging to the array on the LHS of the assignment? So that ptr wouldnt be assigned to anything apart from an empty array during it creation?
What do you mean "during its creation"???
It already exists.
This is not a constructor.
It's assignment.
Presumably the lhs already has something assigned to it.
That must obviously be deleted before the ptr is reassigned.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main()
{
    intArray a{ 3 };
    a[0] = 10;
    a[1] = 20;
    a[2] = 30;

    cout << " a = " << a << "\n\n";  //  a =  [ 10 20 30 ]

    intArray b = a;  // copy constructor called (not assignment)

    cout << " a = " << a << '\n';    //  a =  [ 10 20 30 ] 
    cout << " b = " << b << "\n\n";  //  b =  [ 10 20 30 ] 

    b[1] = 100;

    cout << " a = " << a << '\n';    // a =  [ 10 20 30 ] 
    cout << " b = " << b << "\n\n";  // b =  [ 10 100 30 ] 
    
    a = b;  // assignment operator called

    cout << " a = " << a << '\n';    // a =  [ 10 100 30 ] 
    cout << " b = " << b << '\n';    // b =  [ 10 100 30 ] 
}

So its incase the ptr is pointing to something? I know its not very likely, but i guess this is where my confusion might be coming from. In most examples I see for this, the array is created, then the assignment happens straight afterwards. So the ptr wouldnt point to anything. But I guess, in real cases that would not be likely?

the first pointer is being deleted to clean up the mess. If you don't delete it that's a memory leak.
The ptr may or may not be pointing to something, depending on which constructor was called when the object was created. If the default constructor was called then it will be a nullptr, but it's safe (presumably does nothing) to delete a null pointer. If one of the other constructors was called it will be pointing to some bytes of memory; that memory needs to be freed before the ptr can be reassigned or, as markyrocks notes, that memory will be inaccessible (leak).

Either way, delete [] before reassigning the pointer to some other memory block.
Topic archived. No new replies allowed.