Insert element in array - c++

void insert(int*arr, int element,int index)
{
if (index < SIZE)
{
arr[index] = element;
}
else
{
int* new_array = new int[SIZE + 1];
int i = 0;
for (i = 0; i < SIZE; i++)
{
new_array[i] = arr[i];
}
new_array[i] = element;
SIZE++;
printArray(new_array);
}
}
I have made an insert function in C++ that will insert values at specific indices of the array.After index gets increased I made a new array and copied values from the smaller array into it.
Problem is that printArray function which is just looping to print the array does well when it is called inside the insert function otherwise when I called printArray from the main last value of the array was garbage why is that?

You need to delete the old array and return the new array in its place, e.g.:
void insert(int* &arr, int element, int index) // <<< make `arr` a reference so that we can modify it
{
if (index < SIZE)
{
arr[index] = element;
}
else
{
int* new_array = new int[SIZE + 1];
for (int i = 0; i < SIZE; i++)
{
new_array[i] = arr[i];
}
new_array[SIZE] = element;
SIZE++; // <<< NB: using a global for this is not a great idea!
delete [] arr; // <<< delete old `arr`
arr = new_array; // <<< replace it with `new_array`
}
}
LIVE DEMO
Note that all this explicit low level management of your array goes away if you start using proper C++ idioms, such as std::vector<int> instead of C-style int * arrays.

Related

Push function for dynamic array in c++

I need to implement a push function for a dynamic array. Here's what I've done so far:
#include<iostream>
void printArr(int* arr, int n) {
for (int i = 0; i < n; i++)
std::cout << *(arr + i) << ' ';
}
void push(int* arr, int& size, int e) {
int* tmpArr = new int[size + 1];
for (int i = 0; i < size; i++) { // copying elements to the new array
*(tmpArr + i) = *(arr + i);
}
*(tmpArr + size) = e; // adding new element to the very end of the new array
arr = tmpArr;
size++;
}
int main() {
int size = 0;
int* arr = new int[size];
for (int i = 0; i < 5; i++) {
push(arr, size, i);
printArr(arr, size);
std::cout << std::endl;
}
delete[] arr;
return 0;
}
But it outputs only junk, not expected values.
Here is the output at each iteration.
-33686019
-33686019 -572662307
-33686019 -572662307 1320307911
-33686019 -572662307 1320307911 201336144
-33686019 -572662307 1320307911 201336144 14730656
I tried delete [] arr; before reassigning arr, but it throws a _CrtlsValidHeapPointer(block) exception after the first push() call.
The answer is most likely obvious, but I don't know why this is happening. What should I do to make this code work?
Also I'm wondering if I need to do something with the created tmpArr array after reassigning?

Array resizing. Why cannot I resize the array second time? _CrtIsValidHeapPointer(PUserData)

I want to resize the array multiple times.It does that the first time but after that, it throws me an error. When I do it the second time, I get an error _CrtIsValidHeapPointer(PUserData). Can someone help me out?
int main()
{
int size = 8;
int *arr = new int[size];
arr[1] = 25;
arr[2] = 30;
int count = 0; //to check size
for (int i = 0; i < size; i++)
{
count = count + 1;
}
cout << count << endl;
resize(arr, size);
int new_count = 0; //to confirm size change
for (int i = 0; i < size; i++)
{
new_count = new_count + 1;
}
cout << new_count << endl;
resize(arr, size);
int new_count2 = 0; //to confirm size change
for (int i = 0; i < size; i++)
{
new_count2 = new_count2 + 1;
}
cout << new_count2 << endl;
return 0;
}
void resize(int *a,int &size)
{
int newsize = 2 * size;
int *arr_new = new int[newsize];
for (int i = 0; i < size; i++) //copy everything
{
arr_new[i] = a[i];
}
size = newsize; //new value of size
delete [] a;
a = arr_new; //Pointer pointing to new array
delete arr_new;
}
There are two problems with this code:
void resize(int *a,int &size)
{
[...]
delete [] a;
a = arr_new; //Pointer pointing to new array
delete arr_new; // huh????
}
The first problem is that you are calling the delete operator twice; the first call deletes the old array (which makes sense), but then you attempt to delete the newly allocated array also (via delete arr_new). How is the caller going to able to use the newly allocated array when resize() has already deleted it before it returned?
The second problem is that you set a to point to the new array (i.e. a = arr_new;) but a is a local function-argument that goes out of scope when resize() returns, so the calling code will never see its new value. I think you want this instead:
void resize(int * & a,int &size) // note the & before a!
Passing a by reference will allow the caller to see a's new value after resize() returns.

Deleting a number from an array that is being pointed to?

I'm having a hard time with this little project of mine; can someone help me out? I am trying to take a pointer to an array, a number, and remove the number if it is present in the array. If the number is removed, the array shrinks. Please note at the time of running removeNumber size = 6.
main
{
int size = 5; // setting array size
int *a = new int[size]; // allocating dynamic array
// initializing array
a[0] = 0; a[1] = 10; a[2] = 20; a[3] = 30; a[4] = 40;
removeNumber(a, 10, size);
}
And now the prototype:
void removeNumber(int *& arrayPtr, int number, int &size)
{
int index = check(arrayPtr, number, size);
int *newArray = new int[size - 1];
if (index != -1)
{
for (int i = number; i <= size; ++i)
newArray[i] = *&arrayPtr[i + 1];
delete[] arrayPtr;
arrayPtr = newArray;
size -= 1;
}
}
Check for reference:
int check(int *arrayPtr, int number, int size)
{
for (int i = 0; i < size; i++)
{
if (arrayPtr[i] == number) return i;
}
return -1;
}
The function is wrong. First of all it has a memory leak in case when the target value is not found in the array.
void removeNumber(int *& arrayPtr, int number, int &size)
{
int index = check(arrayPtr, number, size);
int *newArray = new int[size - 1];
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if (index != -1)
{
//...
}
}
Secondly there is used incorrect range of indices
for (int i = number; i <= size; ++i)
^^^^^^ ^^^^^^^^^
newArray[i] = *&arrayPtr[i + 1];
^^^^^^
And you could write this expression *&arrayPtr[i + 1] simpler just like arrayPtr[i + 1].
You forgot to copy the elements of the original array before the index index. number is not a valid index.
Also it would be better if the function returned a Boolean value saying whether the operation was successful or not. You can change the size of the array in the calling function if the call was successful.
So I would write the function like
bool removeNumber( int * &arrayPtr, int n, int value )
{
int index = check( arrayPtr, number, size );
if ( index != -1 )
{
int *tmp = new int[size - 1];
int i = 0;
for ( ; i < index; ++i ) tmp[i] = arrayPtr[i];
for ( ; i < size - 1; i++ ) tmp[i] = arrayPtr[i+1];
delete [] arrayPtr;
arrayPtr = tmp;
}
return index != -1;
}
It is ok to reinvent the wheel in order to learn. However you should be aware of the standard way to handle this: using std::vector along with std::remove/std::remove_if (defined in #include <algorithm>) would make your life much simpler, with the benefit of a performant implementation.
void removeNumber(std::vector<int>& vec, int number) {
vec.erase(std::remove(std::begin(vec), std::end(vec), number),
std::end(vec));
// If you really want to shrink the vector, you can call...
vec.shrink_to_fit();
}
I also made a little demo to show you that it works as intended.
Your problem is here:
for (int i = number; i <= size; ++i)
First of all you start the iteration from the value of the number that you searched(in your case 10) and as a result you will not enter the for loop.So the correct starting value of i is the first number of the array which is 0.Then this line of code here:
newArray[i] = *&arrayPtr[i + 1];
doesn't even make sense(as a thought process not syntactically), but what i think you want to do here is just copy the correct element from the old array to the new one.
A correct implementation of the previous is the following code:
void removeNumber(int *& arrayPtr, int number, int &size)
{
int index = check(arrayPtr, number, size);
if (index != -1)
{
int *newArray = new int[size - 1];
int i = 0,j=0; //i for the old array and j for the new
while(i < size)//while we are in bounds
{
if(i==index)//if the index is the index of the given element
{ //skip this number
i++;
continue;
}
newArray[j++] = arrayPtr[i++];//copy the correct number to the correct position
}
delete[] arrayPtr;
arrayPtr = newArray;
size -= 1;
}
}

Problems changing numbers

looking for some homework help. Not for an answer just for a nudge in the right direction. We are given an array with some numbers, the size of the array and the number of times we are to double it. We are to double the size, copy the same numbers over and then multiply the second halves numbers by 2.
So if the array was {0,1} with number 2. The last array would be {0,1,0,2,0,2,0,4}.
My code compiles properly and is returning some very strange number, which for the original array {0,1} and number 3 is giving me a bunch of 0's and a random 135057 in the middle.
Heres my code:
int *ArrayDynamicAllocation(int array[], int size, int number)
{
for (int runs = 1;runs < number; runs++) {
int new_size = size * 2;
int *new_array = new int[new_size];
for (int x = 0;x < size; x++) {
new_array[x] = array[x];
}
for (int y = size+1; size < new_size; size++) {
new_array[y] = array[y];
}
size = new_size;
array = new_array;
delete [] new_array;
}
return array;
}
As #Elvisjames said in comment, array = new_array; means you are assigning the pointer to the memory of the newly created new_array to array and delete [] new_array; means you are deleting both new_array and array from the memory. Because of previous assignment, array is pointed to the new_array and deleting new_array means deleting array.
So better you delete the old array first then assign the newly created array to the old array.
In your this loop:
for (int y = size+1; size < new_size; size++)
{
new_array[y] = array[y];
}
As #Elvisjames said in comment, new_array[y] = array[y]; where there is no array[y]
You should define your ArrayDynamicAllocation function as following:
int *ArrayDynamicAllocation(int array[], int& size, int number)
{
for (int runs = 1;runs < number; runs++)
{
int new_size = size * 2;
int *new_array = new int[new_size];
for (int x = 0;x < size; x++)
{
new_array[x] = array[x];
new_array[x+size]=2*array[x];
}
size = new_size;
// Here you should delete the old array first then assign the newly created array to the old array.
//array = new_array;
//delete [] new_array;
delete [] array;
array = new_array;
}
return array;
}
I've change the int size to int& size for knowing the new size.

allocating extra memory for a container class

Hey there, I'm writing a template container class and for the past few hours have been trying to allocate new memory for extra data that comes into the container (...hit a brick wall..:| )
template <typename T>
void Container<T>::insert(T item, int index){
if ( index < 0){
cout<<"Invalid location to insert " << index << endl;
return;
}
if (index < sizeC){
//copying original array so that when an item is
//placed in the middleeverything else is shifted forward
T *arryCpy = 0;
int tmpSize = 0;
tmpSize = size();
arryCpy = new T[tmpSize];
int i = 0, j = 0;
for ( i = 0; i < tmpSize; i++){
for ( j = index; j < tmpSize; j++){
arryCpy[i] = elements[j];
}
}
//overwriting and placing item and location index
elements[index] = item;
//copying back everything else after the location at index
int k = 0, l = 0;
for ( k =(index+1), l=0; k < sizeC || l < (sizeC-index); k++,l++){
elements[k] = arryCpy[l];
}
delete[] arryCpy;
arryCpy = 0;
}
//seeing if the location is more than the current capacity
//and hence allocating more memory
if (index+1 > capacityC){
int new_capacity = 0;
int current_size = size();
new_capacity = ((index+1)-capacityC)+capacityC;
//variable for new capacity
T *tmparry2 = 0;
tmparry2 = new T[new_capacity];
int n = 0;
for (n = 0; n < current_size;n++){
tmparry2[n] = elements[n];
}
delete[] elements;
elements = 0;
//copying back what we had before
elements = new T[new_capacity];
int m = 0;
for (m = 0; m < current_size; m++){
elements[m] = tmparry2[m];
}
//placing item
elements[index] = item;
}
else{
elements[index] = item;
}
//increasing the current count
sizeC++;
my testing condition is
Container cnt4(3);
and as soon as i hit the fourth element (when I use for egsomething.insert("random",3);) it crashes and the above doesnt work. where have I gone wrong?
Several things don't make too much sense to me:
if (index+1 > capacityC){
shouldn't that be:
if (index >= capacityC){
Also, when you grow the array I don't see why you are doing two lots of copying. shouldn't:
delete[] elements;
elements = 0;
be:
delete[] elements;
elements = tmparray2;
Note that new T[n] is probably not what you actually want in a container of T, because this already creates n objects of type T. What you really want is to reserve memory, and then at some later point in time construct objects of type T in that memory.
T* data = static_cast<T*>(operator new[](n * sizeof(T)); // allocate memory
// ...
new(&data[size]) T(arguments); // construct T object in-place
++size;
In order to destruct the container, you have to reverse the process: destruct the objects one by one and then release the memory.
while (size) data[--size].~T(); // destruct T object in-place
operator delete[](data); // release memory