#include <iostream>
#include <cstdlib>

using std::cerr;
using std::endl;

/* structure for a heap-allocated array */
struct int_array {
	int n;
	int *a;
};

struct int_array make_int_array( int );
void free_int_array( struct int_array );
void print_int_array( struct int_array );
void copy_int_array( struct int_array , struct int_array);

struct int_array copy( struct int_array );


struct int_array make_int_array( int n )
{
	struct int_array new_array;
	new_array.n = n;
	new_array.a = new int[n];
	return new_array;
}

void free_int_array( struct int_array arr )
{
	delete [](arr.a);
	return;
}

void set_value( struct int_array A , int index , int value )
{
	if ( 0 <= index && index < A.n ) {
		A.a[index] = value;
		return;
	}
	else {
		exit(EXIT_FAILURE);
	}
}

int get_value( struct int_array A , int index )
{
	if ( 0 <= index && index < A.n ) {
		return A.a[index];
	}
	else {
		exit(EXIT_FAILURE);
	}
}

void print_int_array( struct int_array A )
{
	for (int i=0;i<A.n;i++) {
		cout << A.a[i] << endl;
	}
	cout << endl;
	return;
}

// deep copy of B into A (but trashes current contents of A --
// must call free first!
void copy_int_array( struct int_array &A , const struct int_array &B )
{
	A.n = B.n;
	A.a = new int[A.n];
	for (int i=0;i<A.n;i++) {
		A.a[i] = B.a[i];
	}
	
	return;
}

struct int_array copy( struct int_array A )
{
	struct int_array cp;
	cp.n = A.n;
	cp.a = new int[A.n];
	for (int i=0;i<A.n;i++) {
		cp.a[i] = A.a[i];
	}
	
	return cp;
}

int main()
{
	struct int_array A,B;
	
	A = make_int_array( 3 );

	for (int i=0;i<A.n;i++) {
		set_value( A , i , i * i );
	}

	print_int_array( A );

	// shallow copy!!!
	B = A;
	
	set_value(B, 1 , 42 );
	
	print_int_array( B );

	print_int_array( A );	
}