Understanding this code involving pointers, arrays, and the new operator - c++

So this is the original code:
class IntegerArray {
public:
int *data;
int size;
};
int main() {
IntegerArray arr;
arr.size = 2;
arr.data = new int[arr.size];
arr.data[0] = 4; arr.data[1] = 5;
delete[] a.data;
}
After moving arr.data = new int[arr.size] to a constructor, it becomes
class IntegerArray {
public:
int *data;
int size;
IntegerArray(int size) {
data = new int[size];
this->size = size;
}
};
int main() {
IntegerArray arr(2);
arr.data[0] = 4; arr.data[1] = 5;
delete[] arr.data;
}
I'm fairly lost on what the code is trying to do. For
IntegerArray(int size) {
data = new int[size];
this->size = size;
}
Is int size just the same as the int size that was declared in the class IntegerArray?
Does data = new int[size] just tell us that data is pointing to the output of the array at int size, with new saying that the size of the array is variable?
Is this-> size = size just a pointer that tells us that the size value of the constructor is just equal to the size parameter of the class?
Why are arr.data[0] and arr.data[1] even mentioned after IntegerArray arr(2)? They don't seem to follow the constructor, but I'm probably just too tired to comprehend that part.

IntegerArray(int size) {
data = new int[size];
this->size = size;
}
Is int size just the same as ...
This int size:
IntegerArray(int size) {
^^^^^^^^
is an argument to the constructor
Does data = new int[size] just tell us ...
new int[size] dynamically allocates an array that contains size number of int objects. data pointer is then assigned to point to that newly created array.
Is this-> size = size just a pointer ...
No. this is a special pointer, that within the constructor points to the object that is being constructed. this->size is the member variable that was declared here:
class IntegerArray {
public:
int *data;
int size;
^^^^^^^^
The complete expression this->size = size assigns the value size that is the constructor argument, to the member variable size.
Why are arr.data[0] and arr.data[1] even mentioned after IntegerArray arr(2)?
The constructor does not initialize the contents of the array (the integer objects within the array). The mentioned code does assigns a values to them.

this->size = size //the fist size is your member variable which is inside IntegerArray. the 2nd size is the size you give over to the Method
data = new int[size]; // here you are creating a new array with the size of "size"
the method IntegerArray(int size) is a constructor method, you only can call it once per object (even at the time when you create the object)
int main() //the startpoint of your program
{
IntegerArray arr(2); //you are creating a new object with a size of 2
arr.data[0] = 4; arr.data[1] = 5; //because of your array is public, you can call it direct from outside (you sould define it as private ore protected). arr.data[0] is the first item of the array, arr.data[1] is the 2nd item
delete[] arr.data;
}
delete[] arr.data; should be inside the destructor of your class...

Related

How to delete dynamic allocated array in c++?

I got stuck with deleting an dynamically allocated array of int.
I've got a destructor, where I'm trying to use a loop for to delete all elements of array and finally delete it.
I have code on http://rextester.com/OTPPRQ8349
Thanks!
class MyClass
{
public:
int _a;
int* c;
int fRozmiar;
static int fIlosc;
MyClass() //default constructor
{
_a=0;
c = new int [9];
for(int i = 0; i<=9; i++)
{
c[i] = 1;
}
fIlosc++;
}
MyClass(int a1, int c1) // parametrized constructor
{
_a=a1;
c = new int [c1];
for(int i = 0; i<=c1; i++)
{
c[i] = rand();
}
fIlosc++;
}
MyClass(const MyClass &p2) // copy constructor
{
_a =p2._a;
c = p2.c;
fRozmiar = p2.fRozmiar;
fIlosc = fIlosc;
fIlosc++;
}
~MyClass(); // destructor
static int getCount() {
return fIlosc;
}
};
//Initialize static member of class
int MyClass::fIlosc = 0;
MyClass::~MyClass()
{
for(int i = 0; i<sizeof(c); ++i)
{
delete[] c[i];
}
delete[] c;
fIlosc--;
}
int main()
{
}
Remove the for-loop, but keep the delete[] c after it.
Each int doesn't need to be deleted because they're not dynamically allocated. If you needed to delete them, then the for-loop wouldn't work becuase: sizeof(c) is not the size of the array, and delete[] should have been delete instead.
There are several problems in the code.
First, that loop in the destructor must go. If you didn’t new it, don’t delete it.
Second, a loop through an array of N elements should be for (int i = 0; i < N; ++i). Note that the test is i < N, not i <= N. The loops as currently written go off the end of the array. That’s not good.
Third, the copy constructor copies the pointer. When the first object goes out of scope its destructor deletes the array; when the copy goes out of scope its destructor also deletes the array. Again, not good. The copy constructor has to make a copy of the array. In order to do that the class needs to also store the number of elements the array.

How to access dynamic array inside a class constructor?

How do I access the dynamic array and set values to it? For example array[size] = {8, 4, 3, 2, ...}
class Array
{
public:
Array(int sze)// default constructor
{
size = sze;
ptr = new int [size];
}
private:
int size; // number of elements in the Array
int *ptr = 0; // address of dynamically allocated memory
};
int main()
{
Array arry(10);
cout << arry.getSize();
//.....;
}
Your array that you have created is private, and to access it you must provide an accessor method:
public:
...
int* getPtr() { return ptr; }
...
int *ptr = arry.getPtr();
ptr[0] = 1;
cout << ptr[0];
Alternatively you can hide the pointer itself and provide get(position) and set(position) methods to ensure that other code doesn't mess with your pointer.

Construct object, where one of its properties depends on another. In C++

Beginner in C++
I have a class, say
class A
{
public:
int N;
double .....
};
But I would like the ..... to define a matrix of size depending on N. In case that changes the approach, it is a non-identical function of N and not just N itself, say N^3+1.
In case that is the approach, I have never written a constructor of an object in C++. Therefore, if this is the approach could you please give some detail. I don't understand how it might work. When the class is instanciated, maybe the property N hasn't been even initialized.
I am not clear how to get a matrix or array (I am still not clear of the basic data types of C++) of size determined in execution.
Edit: The value of N is determined later in the code. It is something like:
A InstanceOfA; //The variable InstanceOfA is declared of type A.
...
Some other stuff happens, e.g. other properties of InstanceOfA are initialized
and some of the functions are used. And then:
...
A.setN(4);
I didn't understand from the answer below. Would I need to do
A InstanceOfA(4);
?
You can use std::vector
class A
{
public:
int N; // you should use int for size
double std::vector<std::vector<double>> matrix; //define the matrix
//initialize it in the constructor
A( int size ):N(size), matrix(size*3+3)// or you can use any expression that evaluates an integral value
{
//you can initialize the values in matrix here
}
};
Note
the expression matrix(size*3+3) initializes the matrix such that, there are size*3+3 rows, the number of columns in each row are not specified yet. You can also specify column sizes in the constructor like
for( int i=0;i< N*3+3; ++i) //for each row
{
matrix[i].resize(N*2);// resize each col to hold N*2 cells,
}
Edit
As per the modification in question, you can then leave the constructor empty (or initialize any other members), and provide a setSize method in class A, which will later initialize the size.
void setSize(int size){
N= size;
matrix.resize( size*3+3);
for( int i=0;i< N*3+3; ++i) //for each row
{
matrix[i].resize(N*2);// resize each col to hold N*2 cells,
}
}
Then you can use it like:
A instanceOfA;
//other code
//
instanceOfA.setSize(N);
You can use an std::vector<std::vector<double>> to capture the matrix. Also, change the type of N to int.
class A
{
public:
int N;
std::vector<std::vector<double>> matrix;
};
Define a constructor and initialize the data in the constructor.
class A
{
public:
A(int n) : N(n)
{
int matrixSize = N*N*N+1;
for (int i = 0; i < matrixSize; ++i )
{
matrix.push_back(std::vecotr<double>(matrixSize));
}
}
double N;
std::vector<std::vector<double>> matrix;
};
One possible way is to do it with a pointer. If you only allocate your array in constructor and its size will not change during the lifetime of your object, that could be done in this way:
class A
{
public:
double N;
double* arr;
A(double aN):N(aN)
{ arr = new double[3*N+1]; // allocate your array in constructor
... // do whatever else you need to initialize your object
}
...
~A() { delete[] arr;} // free it in destructor
...
}
See also the tutorial on Dynamic Memory.
You will then instantiate your class in one of two ways:
A a(aN);
// this object will be automatically destroyed when it gets out of scope, for example at the end of the function where it was created
A* a = new A(aN);
// this object will have to be deleted by yourself when it's no longer needed:
...
delete a;
If you don't know N at the moment when you create your object, you can postpone the allocation :
class A
{
public:
double N;
double* arr = NULL;
A() { ... } // do whatever you need in your constructor
setN(double aN)
{
N = aN;
arr = new double[3*N+1]; // allocate your array
}
...
~A() { if(arr) delete[] arr;} // free your array in destructor if needed
...
}
then you can call your object as:
A a;

Create Array Using Pointers

i'm working on a array header from base definition of an array to create an array of any type with this header,so i created a array class with functions and constructors.
this is my code so far:
#include <iostream>
#define newline "\n"
class Arr
{
public:
typedef float T;
public:
Arr(int size);
Arr(int size, T fill);
T get(unsigned index) const;
void set(unsigned index, T newvalue);
unsigned Size() const;
unsigned SIZE;
void Print();
private:
};
Arr::Arr(int size,T fill)
{
SIZE = size;
T *pointer;
for (int i = 0; i < size; i++)
{
*pointer = fill;
pointer++;
}
}
void Arr::set(unsigned index, T newvalue)
{
T *pointer;
pointer = 0;
for (unsigned i = 0; i < index; i++)
{
pointer++;
}
*pointer = newvalue;
}
void Arr::Print()
{
T *pointer;
pointer = 0;
for (unsigned i = 0; i < SIZE; i++)
{
std::cout << *pointer << newline;
pointer++;
}
}
i know that my pointer point to nothing,as my question is my pointer should point to what to make this code work correctly?!
any time i point it to 0 after debug it crashes!
thanks...!
Pointers are tricky part of c++.
Here is a good link to get you started
http://www.codeproject.com/Articles/7042/How-to-interpret-complex-C-C-declarations
The reason your code doesn't work is a memory block for the array pointed to by the pointer is not allocated. You have to use the predecessor new in-order to achieve that.
Here an example
int size;
T arr;
T* ptr_2_arr;
ptr_2_arr = new T[size];
To retrieve elements of the array you can loop the array using a for loop
*ptr_2_arr[i];
hope this helps.
Post the problem statement if you need more detail
You must make a data member of the class that will point to the allocated memory for the array. Also you need to define a copy constructor, the copy assignment operator and the destructor.
Also it would be better that type of parameter size of constructors coinsides with the type of data member SIZE, I do not understand why this variable is written in capital letters.
ALso there is no any sense to make the data member SIZE and the function Size() public. if SIZE is public it can be changed by the user at any moment.
Make sure you specify the size of the array in your constructor.
SIZE = size;
pointer = new T[size]; //this is where I see an issue. Specify the size of your array.
for (int i = 0; i < size; i++)
{
*(pointer + i) = fill; //This is fine but you are filling up the array with only one number, fill. Nothing wrong with that if that is you intention. Try (*(pointer + i) = i; for i though size elements.
}

How to pass an Array into a Class in C++

When i create a class I would like to be able to store an array in that class. Is this possible?
For example. If i have a class called array to store an array from my main function
int main()
{
double nums[3] = {1 2 3}
array Vnums(nums)
return 0
}
class array
{
public
//constructor
array(double nums[])
{
double vector[] = nums;
}// end constructor
}// end array
Thank you!
use a std::array instead of a raw array. It's just like a raw array, but copiable, and has useful member functions.
class array
{
std::array<double, 3> classArray;
public:
//constructor
explicit array(const std::array<double, 3>& rhs)
:classArray(rhs)
{}// end constructor
}// end array
int main()
{
std::array<double, 3> nums = {{1 2 3}};
array Vnums(nums)
return 0
}
or maybe a std::vector if you want to be able to change the size at will
class array
{
std::vector<double> classArray;
public:
//constructor
explicit array(const std::vector<double>& rhs)
:classArray(rhs)
{}// end constructor
}// end array
int main()
{
std::vector<double> nums{1 2 3}; //C++11 feature
array Vnums(nums)
return 0
}
I'm not sure what you're doing, so it's hard to give solid advice. You can pass a raw array by reference, a pointer and a count, an iterator pair...
Yes, but you must either allocate the array dynamically upon class creation, or the array must always be the same size.
Option A:
class array{
private:
double* data;
unsigned size;
public:
array(double* d, unsigned s){
size = s;
data = new double[size];
for(unsigned i = 0; i < s; i++)
data[i]=d[i];
}
array(const array& copy){
double* temp = new double[copy.size];
delete [] data;
data = temp;
size = copy.size;
for(unsigned i = 0; i < size; i++)
temp[i]=copy.data[i];
}
array& operator= (const array& copy){
double* temp = new double[copy.size];
delete [] data;
data = temp;
size = copy.size;
for(unsigned i = 0; i < size; i++) data[i]=copy.data[i];
}
~array(){
delete[] data; // Don't forget the destructor!
}
};
This is probably the way you need, but note that you will almost certainly need the custom copy constructor and assignment operator so that you don't share any memory between multiple instances of this class. A better way might be to make a copy function that both can use.
Option B:
class array{
private:
double data[3];
public:
array(double* d){ //or "double(&d)[3]" to be safer, but less flexible
for(unsigned i = 0; i < 3; i++){
data[i] = d[i]; // If d is not at least size 3, your program will crash here (or later on, or maybe just act in an undefined way)
}
}
}
Haven't tested this, but it should be an ok starting point.