c++ initial value of dynamic array - c++

I need to dynamically create an array of integer. I've found that when using a static array the syntax
int a [5]={0};
initializes correctly the value of all elements to 0.
Is there a way to do something similar when creating a dynamic array like
int* a = new int[size];
without having to loop over all elements of the a array? or maybe assigning the value with a for loop is still the optimal way to go?
Thanks

Sure, just use () for value-initialization:
int* ptr = new int[size]();
(taken from this answer to my earlier closely related question)

I'd do:
int* a = new int[size];
memset(a, 0, size*sizeof(int));

I'd advise you to use std::vector<int> or std::array<int,5>

Value initialize the elements with ()
Example:
int *p = new int[10]; // block of ten uninitialized ints
int *p2 = new int[10](); // block of ten ints value initialized to 0

To initialize with other values than 0,
for pointer array:
int size = 10;
int initVal = 47;
int *ptrArr = new int[size];
std::fill_n(ptrArr, size, initVal);
std::cout << *(ptrArr + 4) << std::endl;
std::cout << ptrArr[4] << std::endl;
For non pointer array
int size = 10;
int initVal = 47;
int arr[size];
std::fill_n(arr, size, initVal);
Works pretty Much for any DataType!
!Be careful, some compilers might not complain accessing a value out of the range of the array which might return a non-zero value

int *a=new int[n];
memset(a, 0, n*sizeof(int));
That sets the all the bytes of the array to 0. For char * too, you could use memset.
See http://www.cplusplus.com/reference/clibrary/cstring/memset/ for a more formal definition and usage.

Related

Getting the length of an array when passed to another function

int *getNewArray(int arr[])
{
int newArray[15];
int len = sizeof(arr) / sizeof(arr[0]);
std::cout << len;
return newArray;
}
int main()
{
int arr[3] = {1, 2, 3};
int * newArr = getNewArray(arr);
return 0;
}
Why is the sizeof(arr) / sizeof(arr[0]) returning me 2 instead of 3? What is the right way to get the length of the passed array?
You have two problems:
Firstly, your array has automatic storage. Automatic objects are destroyed automatically at the end of scope. As such, the array no longer exists after the function returns. You return a pointer to the first element of array that does not exist after the function. The returned pointer is always invalid and therefore useless.
Secondly, there is no general way to know the size of the pointer based on a pointer to element of that array. Typically, you would pass the size of the array along with the pointer.
sizeof(arr) = 8 (on 64 bit system). Its a plain pointer
sizeof(arr[0]0 = 4 (if int is 32 bit)
hence the 2.
use std::vector or std::array
I guess the Optimized code will look something like this , maintaining the actual functionality as it is by using std::vector.
For more details I will recommend this link Vector in C++.
#include<iostream>
#include<vector>
using namespace std;
vector<int > getNewArray(vector<int >& arr)
{
int *newArray = new int[15];//creating an array of size 15 in heap
int len = arr.size();
std::cout << len;
return newArray;
}
int main()
{
vector<int > arr = {1, 2, 3};
vector<int > newArr = getNewArray(arr);
return 0;
}

How is memory allocated in this line of code "int **v = new int*[n]; "?

int **v = new int*[n];
I'm confused as to what this does? could someone please explain?
This allocates an array of n pointers to int. A pointer to the first element in this array of pointers is stored in v. It is a double pointer, such that accessing an element via v[i] returns a stored pointer from the array.
it's not correctly complete:
int **v = new int*[n];
we'd think this means to allocates dynamically array of integer array on memory, so the dimension must suit it
statically equivalent
const size_t n=5;
int *v[n] = {} ;
// or
int v[][n] ={ {1,2,3,4,5}, {6,7,8}, {9,8,7,6,5} }; //2 dimensional array
as max size of first dimension is inferred automatically to be 3 but
I guess IMHO, this is not yet given,
int **v = new int*[n];
so it'd be specified as
int **v = new int*[n * 3];

Declaring an array of pointers in C++

When I make an array of integer pointers, I tried this.
int *arr = new int*[10];
This did not work but the following worked.
int **arr = new int*[10];
Why do we need double pointer?? And when I deference it, I had to do the following.
cout<<arr[0];
Why we do not need * in front of arr??
thanks!
new int*[10] allocates an array of ten pointers, and it yields a pointer to the first element of that array. The element type is itself a pointer, that's why you end up having a pointer to a pointer (to int), which is int**. And obviously int** isn't convertible to int*, so you have to declare arr with the appropriate type.
You are not just "making an array of integer pointers": you are dynamically allocating them.
Just like when you dynamically allocate an array of integers you get a single pointer through which to access them:
int* ptr = new int[5];
when you dynamically allocate an array of pointers-to-integer you get a single pointer through which to access those, too; since your element type is int*, adding the extra * gives you int**:
int** ptr = new int*[5];
As for dereferencing, I'm not quite sure what you're asking but that's just how the [] operator works; it adds n to a pointer then dereferences it:
int* ptr = new int[5];
*(ptr+1) = 42; // identical
ptr[1] = 42; // to this
If you forget dynamic allocation and just make a nice array, it's all much simpler:
int* array[5];
std::cout << array[0];
This statement is an expression for an 1D array of int
int* arr = new int [10]; // pointer to array of 10 int
This statement is an expression for a 2D array of int
int** arr = new int* [10]; // pointer to 10 pointers to arrays of 10 int
To populate the 1D array, you need to do this...
for (int i = 0; i < 10; i++) {
arr[i] = val; // where val can be any integer
}
To populate the 2D array, you need to do this...
int** arr2 = new int*[10];
for (int i = 0; i < 10; i++) {
arr2[i] = new int[10];
for (int j = 0; j < 10; j++) {
arr2[i][j] = val; // where val can be any integer
}
}
The * symbol between the variable type and the variable name is syntax for pointer. It changes type from int to pointer of int.

Can't declare dynamic 2D array in C++ [duplicate]

This question already has answers here:
How do I declare a 2d array in C++ using new?
(29 answers)
Closed 8 years ago.
I've stuck on a problem - I can't declare 2D arrays in C++ using integers, written by user.
This code works fine-
cin>>m>>n;
int *array;
array=new int[m*n];
But I can't make this work -
cin>>m>>n;
int *array;
array=new int[m][n];
Any ideas how i can bypass it?
P.S. the error : cannot convert 'int ()[2]' to 'int' in assignment.
Change
cin>>m>>n;
int *array;
array=new int[m][n];
to
cin>>m>>n;
int **array;
array=new int * [m];
for ( int i = 0; i < m; i++ ) array[i] = new int[n];
array is int * and you try to assign int **... change array to int**.
2D array is actually array of arrays, so you need pointer to pointer.
That's because you can only use new to allocate 1D arrays. In fact, 2D arrays are also 1D arrays, where, in most systems, all rows are simply concatenated. That is called a row-major memory layout.
You can emulate 2D arrays with a 1D array. The index conversion is:
index1 = y * m + x
This also has much better performance than creating one array per row, as recommended in the "duplicate" link or in other answers.
Just as Domi said (but not index1=y*m+x but rather index1=x*n+y to emulate your desired notation):
int *array = new int [m*n];
int get (int x, int y) // emulates array[x][y] for array[m][n]
{
return array[x*n+y];
}
However, I think the real 2-dimensional allocation (as Vlad from Moscow showed you) is slower in creation (and needs a bit more memory), but quicker in accessing. Cause array[x*n+y] == *(array+x*n+y), wether array[x][y] == *(*(array+x)+y), so you have one multiplication less, but one dereferenciation more, in sum I think it's quicker.
You could also create a class:
class array2d
{
private:
int *data;
int mm, nn;
public:
array2d (int m, int n)
{
mm = m;
nn = n;
data = new int [m*n];
}
~array2d ()
{
delete[] data;
}
int *operator[] (int x)
{
return (data+x*nn);
}
};
With it you can use
array2d arr(10,10);
arr[5][7] = 1;
You can do this:
typedef int RowType[n];
RowType *array = new RowType[m];
doStuffWith(array[y][x]);
Or, even shorter (but harder to remember):
int (*array)[n] = new (int[m][n]);
Edit:
There is a catch in C++ that array sizes must be constant for the new operator, so you can only do this if n is const. This is not a problem in C (and the reason I forgot about this), so the following works even if n and m are not const:
RowType *array = (RowType*)malloc(m * sizeof(RowType));
Of course, you can work around this restriction in C++ by doing this, which works even if both m and n are dynamic:
RowType *array = (RowType*)new int[m * n];
The typedef free version would be this:
int (*array)[n] = (int (*)[n])new int[m *n];
Firstly I suggest you should use std::vector to avoid memory allocation / deallocation issues.
In case you want an array implementation, then you can declare array as a pointer to pointer to int.
cin >> m >> n;
int** array = new int* [m];
for ( int I = 0; I < m; I++ ) {
array[I] = new int[n];
}

New and arrays size

I have a dynamically created array of integers. Now I have to remove all elements which have index %3 == 0. (for example, 3, 6, 9, ...). So, what is the best way to decrease array size? With malloc I can use realloc for the same part of memory, but what about new operator? What to do this way. Just slide all elements left, make zero to all another elements?
#include <algorithm>
#include <iostream>
#include <vector>
bool IsDividedByThree (int i) { return ((i%3)==0); }
int RandomNumber () { return (rand()%100); }
int main()
{
std::vector<int> myInts(50);
std::generate(myInts.begin(), myInts.end(), RandomNumber);
std::copy(myInts.begin(), myInts.end(), std::ostream_iterator<int>(std::cout, " "));
myInts.erase(std::remove_if(myInts.begin(), myInts.end(), IsDividedByThree), myInts.end());
std::copy(myInts.begin(), myInts.end(), std::ostream_iterator<int>(std::cout, " "));
}
Isn't so nice that STL takes care everything for you?
Hm didn't see comment, in which one is forced not to use STL.
The C version:
int *temp = new int[NEW_SIZE];
memcpy( temp , old_array, size_of_old_array * sizeof(int) );
delete[] old_array;
old_array = temp;
create the array dynamically
create a new array with the new size
copy the elements from the first to the second array
delete the first array
redirect the pointer to the first array to the second
All these answer So, what is the best way to decrease array size? - I assumed you already knew how to solve the rest of your problem.
I'd simply allocate a new smaller array and then copy elements to it. Something like this (this includes the element at 0 index):
int* array = new int [original_size];
// fill array
size_t new_size = original_size - original_size / 3 - 1; // i think i got this right, untested
int* new_array = new int [new_size];
for (int i = 0, int j = 0; i < original_size; i++)
{
if (i % 3 == 0)
{
new_array[j] = array[i];
j++
}
}
delete [] array;
array = new_array;
new_array = nullptr;
You can of course work in place and shift elements to the left. But you can't delete a part of array that was allocated via new[].
Since this is an exercise, and you can't use STL, why don't you try to implement a simple vector class yourself?
You can use placement new operator in C++. (#include <new> is required). For example
#include <new>
int main(int argc, char **argv) {
double *b = new double[10];
new(b) double[8];
delete [] b;
}
Simply setting data elements to 0 wont free them. And when you allocate new memory for the resized array, you need to copy all of the elements from previous memory.
I would suggest you to implement it as a linked list.