New and arrays size - c++

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.

Related

I have used new keyword to create two arrays but cant take input for second array [duplicate]

How to create a dynamic array of integers in C++ using the new keyword?
int main()
{
int size;
std::cin >> size;
int *array = new int[size];
delete [] array;
return 0;
}
Don't forget to delete every array you allocate with new.
Since C++11, there's a safe alternative to new[] and delete[] which is zero-overhead unlike std::vector:
std::unique_ptr<int[]> array(new int[size]);
In C++14:
auto array = std::make_unique<int[]>(size);
Both of the above rely on the same header file, #include <memory>
You might want to consider using the Standard Template Library . It's simple and easy to use, plus you don't have to worry about memory allocations.
http://www.cplusplus.com/reference/stl/vector/vector/
int size = 5; // declare the size of the vector
vector<int> myvector(size, 0); // create a vector to hold "size" int's
// all initialized to zero
myvector[0] = 1234; // assign values like a c++ array
int* array = new int[size];
As soon as question is about dynamic array you may want not just to create array with variable size, but also to change it's size during runtime. Here is an example with memcpy, you can use memcpy_s or std::copy as well. Depending on compiler, <memory.h> or <string.h> may be required. When using this functions you allocate new memory region, copy values of original memory regions to it and then release them.
// create desired array dynamically
size_t length;
length = 100; //for example
int *array = new int[length];
// now let's change is's size - e.g. add 50 new elements
size_t added = 50;
int *added_array = new int[added];
/*
somehow set values to given arrays
*/
// add elements to array
int* temp = new int[length + added];
memcpy(temp, array, length * sizeof(int));
memcpy(temp + length, added_array, added * sizeof(int));
delete[] array;
array = temp;
You may use constant 4 instead of sizeof(int).
dynamically allocate some memory using new:
int* array = new int[SIZE];
The answers above are all good for assigning one-dimensional int-arrays. Anyhow, I want to add that it is also possible to do this for multi-dimensional arrays you'd normally define like int[][] matrix = {{1,2}, {3,4}}.
The key is that you store all elements in one array and make use of the fact that the array is a continuous block in memory (see here for a clarification of "block"), meaning that you can "slice" yourself through dimensions. Below you can see an example for a 2d-array.
You can find a discussion regarding this topic here on SO.
/*Defining a 2d-matrix.*/
struct Matrix {
int rows, columns;
int* matrix;
Matrix(int rows, int columns) : rows(rows), columns(columns) {
// This approach uses a single array since "new" cannot create
// multidimensional arrays.
// It also spares the performance cost of an array of arrays.
matrix = new int[columns * rows];
}
~Matrix() {
// Release the memory after destroying the Matrix-object
delete[] matrix;
}
/*Access the element at position [r]ow and [c]olumn.*/
int getElement(int r, int c) {
// matrix[c][r] is rewritten as matrix[column + columns * rows]
// -> matrix <=> Single memory block
return matrix[c + columns * r];
}
/*Set the element at position [r]ow and [c]olumn with given [val]ue.*/
void setElement(int r, int c, int val) {
matrix[c + columns * r] = val;
}
};
An example to populate such a Matrix-object would be:
/*Initialize the matrix with the continuous numbers 0..N*/
void Matrix::initDummyMatrix(){
int counter = 0;
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < columns; ++col) {
setElement(row, col, counter++);
}
}
}
#include <stdio.h>
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
float arr[2095879];
long k,i;
char ch[100];
k=0;
do{
cin>>ch;
arr[k]=atof(ch);
k++;
}while(ch[0]=='0');
cout<<"Array output"<<endl;
for(i=0;i<k;i++){
cout<<arr[i]<<endl;
}
return 0;
}
The above code works, the maximum float or int array size that could be defined was with size 2095879, and exit condition would be non zero beginning input number

Why use a dynamic array instead of a regular array?

The following code is used to demonstrate how to insert a new value in a dynamic array:
#include <iostream>
int main()
{
int* items = new int[5] {1, 2, 3, 4, 5}; // I have 5 items
for (int i = 0; i < 5; i++)
std::cout << items[i] << std::endl;
// oh, I found a new item. I'm going to add it to my collection.
// I do this by
// (1) allocating a bigger dynamic array
// (2) copying the existing elements from the old array to the new array
// (3) deleting the old array, redirecting its pointer to the new array
int* items_temp = new int[6];
for (int i = 0; i < 5; i++)
items_temp[i] = items[i];
items_temp[5] = 42;
delete[] items;
items = items_temp;
for (int i = 0; i < 6; i++)
std::cout << items[i] << std::endl;
delete[] items;
}
I am confused about the necessity of using it over a regular array. Can't I just do the same thing with a regular array? Basically, you just define a new array with a larger size and move elements in the previous array to this new array. Why is it better to use a dynamic array here?
You are right, the example you are looking at isn't very good at demonstrating the need for dynamic arrays, but what if instead of going from size 5->6, we had no idea how many items we found until we need to add until the code is actually running?
Regular arrays need to be constructed with their size known at compile time
int foo [5] = { 16, 2, 77, 40, 12071 };
But dynamic arrays can be be assigned as size at runtime
int* Arrary(int size) {
return new int[size];
}
So if you don't know the size of your array, or it may need to grow/shrink you need to use a dynamic array (or better yet just use a std::vector).
Suppose you want to do what you mentioned a multiple times.
for(int i = 0; i < some_val; ++i)
{
int val_to_add;
std::cin >> val_to_add;
int* new_arr = new int[old_size + 1]; // the value is suppsoed to be big in order to indicate that it takes much memory.
copy_old_to_new(new_arr, old_arr); //some function which does the copying.
new_arr[old_size + 1] = val_to_add;
delete[] old_arr;
old_arr = new_arr;
}
Now think about what would happen if we tried to do the same with static arrays.
We wouldn't be able to remove the memory allocated by the old_arr, and the program would use a lot of memory.
We wouldn't be able to construct an array which would be accessible outside the loop, which, obviously, is not intended.
In your example it is not much clear how the usage of dynamic arrays would make use in your intention. So if you feel you could do the same without dynamic arrays, do it without them.

How to make a dynamically growing struck array in C++ [duplicate]

How to create a dynamic array of integers in C++ using the new keyword?
int main()
{
int size;
std::cin >> size;
int *array = new int[size];
delete [] array;
return 0;
}
Don't forget to delete every array you allocate with new.
Since C++11, there's a safe alternative to new[] and delete[] which is zero-overhead unlike std::vector:
std::unique_ptr<int[]> array(new int[size]);
In C++14:
auto array = std::make_unique<int[]>(size);
Both of the above rely on the same header file, #include <memory>
You might want to consider using the Standard Template Library . It's simple and easy to use, plus you don't have to worry about memory allocations.
http://www.cplusplus.com/reference/stl/vector/vector/
int size = 5; // declare the size of the vector
vector<int> myvector(size, 0); // create a vector to hold "size" int's
// all initialized to zero
myvector[0] = 1234; // assign values like a c++ array
int* array = new int[size];
As soon as question is about dynamic array you may want not just to create array with variable size, but also to change it's size during runtime. Here is an example with memcpy, you can use memcpy_s or std::copy as well. Depending on compiler, <memory.h> or <string.h> may be required. When using this functions you allocate new memory region, copy values of original memory regions to it and then release them.
// create desired array dynamically
size_t length;
length = 100; //for example
int *array = new int[length];
// now let's change is's size - e.g. add 50 new elements
size_t added = 50;
int *added_array = new int[added];
/*
somehow set values to given arrays
*/
// add elements to array
int* temp = new int[length + added];
memcpy(temp, array, length * sizeof(int));
memcpy(temp + length, added_array, added * sizeof(int));
delete[] array;
array = temp;
You may use constant 4 instead of sizeof(int).
dynamically allocate some memory using new:
int* array = new int[SIZE];
The answers above are all good for assigning one-dimensional int-arrays. Anyhow, I want to add that it is also possible to do this for multi-dimensional arrays you'd normally define like int[][] matrix = {{1,2}, {3,4}}.
The key is that you store all elements in one array and make use of the fact that the array is a continuous block in memory (see here for a clarification of "block"), meaning that you can "slice" yourself through dimensions. Below you can see an example for a 2d-array.
You can find a discussion regarding this topic here on SO.
/*Defining a 2d-matrix.*/
struct Matrix {
int rows, columns;
int* matrix;
Matrix(int rows, int columns) : rows(rows), columns(columns) {
// This approach uses a single array since "new" cannot create
// multidimensional arrays.
// It also spares the performance cost of an array of arrays.
matrix = new int[columns * rows];
}
~Matrix() {
// Release the memory after destroying the Matrix-object
delete[] matrix;
}
/*Access the element at position [r]ow and [c]olumn.*/
int getElement(int r, int c) {
// matrix[c][r] is rewritten as matrix[column + columns * rows]
// -> matrix <=> Single memory block
return matrix[c + columns * r];
}
/*Set the element at position [r]ow and [c]olumn with given [val]ue.*/
void setElement(int r, int c, int val) {
matrix[c + columns * r] = val;
}
};
An example to populate such a Matrix-object would be:
/*Initialize the matrix with the continuous numbers 0..N*/
void Matrix::initDummyMatrix(){
int counter = 0;
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < columns; ++col) {
setElement(row, col, counter++);
}
}
}
#include <stdio.h>
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
float arr[2095879];
long k,i;
char ch[100];
k=0;
do{
cin>>ch;
arr[k]=atof(ch);
k++;
}while(ch[0]=='0');
cout<<"Array output"<<endl;
for(i=0;i<k;i++){
cout<<arr[i]<<endl;
}
return 0;
}
The above code works, the maximum float or int array size that could be defined was with size 2095879, and exit condition would be non zero beginning input number

how do i create dynamic array in cpp

I have this function:
void reverse(int* nums, unsigned int size)
This function is supposed to reverse the values in the array it is getting.
Now for reversing I thought to create another array with the size of the array passed in. Assigning this new one from the end of the original array to the start.
But I am a kind of new in C++, So I don't know how to create dynamic array in the size of the parameter of the function.
It's actually not necessary to allocate a new array here. See if you can find a way to solve this problem just by rearranging the existing elements in-place.
Given that this seems like it's an exercise with pointers, you can allocate space by using the new[] operator:
int* auxiliaryArray = new int[size];
You'd then free it by writing
delete[] auxiliaryArray;
However, this isn't the preferred way of doing this in C++. The better route is to use std::vector, which does all its own memory management. That would look like this:
std::vector<int> auxSpace(size);
You can then access elements using the square brackets as you could in a real array. To do this, you'll need to #include <vector> at the top of your program.
In C++, the recommended way to create an array of variable size would be to use an std::vector
#include <vector>
void reverse(int* nums, unsigned int size)
{
std::vector<int> V(size);
...
}
But that approach isn't the best here for performance because it requires additional memory to be allocated of the size of the array, which could be big. It would be better to start from the outside of the array and swap members one by one that are at mirroring positions (so if the size is 5, swap 0 and 4, then swap 1 and 3 and leave 2 alone). This only requires temporary storage of a single int.
You can do it without the need to create another array:
void reverse(int* array, const int size){
for(int i = 0; i < size / 2; i++){
int tmp = array[i];
array[i] = array[size - 1 - i];
array[size - 1 - i] = tmp;
}
}
int main(){
int array[] = {1, 3, 5, 7, 9, 11};
const int size = sizeof(array) / sizeof(array[0]);
reverse(array, size);
for(int i(0); i < size; i++)
std::cout << array[i] << ", ";
}
As you can see above in the loop you only need to swap the first element (element 0) with the n-1 element and the second one with n-1-1 and son on...
Remember arrays are indexed from 0 through n-1.
If you want to allocate new array which is not practical:
int* reverse2(int* array, const int size){
int* tmp = new int[size];
for(int i(size - 1), j(0); j < size; j++, i--)
tmp[j] = array[i];
return tmp;
}
int main(){
int array[] = {1, 3, 5, 7, 9, 11};
for(int i(0); i < size; i++)
std::cout << array[i] << ", ";
std::cout << std::endl;
int* newArray = reverse2(array, size);
for(int i(0) ; i < size; i++)
std::cout << newArray[i] << ", ";
std::cout << std::endl;
delete[] newArray;
return 0;
}
If you want to use a new array you can, but I think is to kill flies with a cannon.
Looks like you are using plain C code and not C++. I say that because of the signature of the function. The signature of the function in a common C++ code could be something like this other:
void reverse(std::vector& items);
You can reverse the current array without a new array, using the current one. You are passing the pointer to the first item of the array, and the content is not constant so that you can modify it. A better signature for the function could be:
void reverse(int* const nums, const unsigned int size);
Looks like a pointer problem. Think about the boundaries to iterate the positions of the array. Would you need to iterate the whole array? Maybe only half array? ;)
As bonus track, what about to exchange the values without an auxiliar variable? (this is true into this case that we are using the fundamental type int... remember the binary arithmetic).
array[pos_head] ^= array[pos_tail];
array[pos_tail] ^= array[pos_head];
array[pos_head] ^= array[pos_tail];

How to can I print values using vectors and how can I add a value to the end of an array?

I have two questions:
1- How can print the values of a for the code stated below???
#include <iostream>
#include <list>
using namespace std;
int main()
{
int i;
list<int> a;
for(i; i<5; i++)
{
a.push_back(i);
}
system("pause");
return 0;
}
2- How can I add new element to an integer array? For example, I have an array such that:
int *a;
int size = 3
a = new int [size];
a[0]=0;
a[1]=1;
a[2]=2;
//Now, I would like to add a new element to my array by increasing its size by one
size += size; // new size is 4
How can I use my array with the new size and add a new element to the end of the array?
(1)
list<int>::const_iterator it;
for (it = a.begin(); it != a.end(); ++it)
cout << *it << endl;
(2) Create a 2nd array with new[] and copy over the first. Remember to delete[] the original. Or, better yet, get rid of the array and use a vector and just push back the new element(s). Vectors automatically resize themselves.
You should initialize i to 0 in the for() loop.
To print the values you have to make another for() loop but instead of adding elements to the list you print them to cout.
for(...)
{
// print to cout
}
int* b = new int[size + 1];
The you should use memcpy() to copy a into b, and then add the last element to b.
At the end you should call delete for a and b also.
1. Prefer std algorithms to hand-coded for loops:
std::copy(list.begin(), list.end(),
std::ostream_iterator<int>(std::cout, "\n"));
If hand-coding the loop is still the right choice, consider Boost.Foreach:
BOOST_FOREACH(int i, list) {
std::cout << i << "\n";
}
2 This is one reason why you should use std containers instead of pointers and arrays. Let somebody else debug the hard code.
int* newa = new int[newsize];
std::copy(a, a+std::min(newsize, size), newa);
delete[] a;
a = newa;
size = newsize;
But, does this code leave the extra items initialized or uninitialized? What exception guarantees does this code offer? Better to skip the new altogether and just declare a std::vector.