How to dynamically increase the array size? - c++

I've been trying to make a program that adds 2 arrays of different size. But I would like to know to to dynamically increase the array size capacity? Ex: array[4] then upgrade the size to 2 to make array[6];?
EDIT: WIthout using vectors
I tried creating a new ptr but it does not work. I get the error: Read only variable is not assignable.
int *ptr2 = new int[a2.size];
// new ptr2 copies ptr1
for (int i=0; i<(a1.size); i++) {
ptr2[i] = a1.ptr[i];
}
// we want ptr1 to point to ptr2
for (int i=0; i<(a2.size); i++) {
ptr2[i] += a2.ptr[i];
}
delete [] a1.ptr;
a1.ptr=ptr2;

You can't change the size of the array, but you don't need to. You can just allocate a new array that's larger, copy the values you want to keep, delete the original array, and change the member variable to point to the new array.
Allocate a new[] array and store it in a temporary pointer.
Copy over the previous values that you want to keep.
Delete[] the old array.
Change the member variables, ptr and size to point to the new array and hold the new size.

int* newArr = new int[new_size];
std::copy(oldArr, oldArr + std::min(old_size, new_size), newArr);
delete[] oldArr;
oldArr = newArr;

#include<bits/stdc++.h>
using namespace std;
main(){
int *p = new int[5]; // locate memory in heap
int *q = new int[10];// locate memory in heap
for(int j=0; j<5;j++)
p[j] = j;
for(int i=0; i<5;i++)
q[i] = p[i];
delete []p;//Delete the old array 'p'
p = q; // Assign the pointer of 'q' to 'p'
q = NULL; // delete the location of pointer 'q'
return 0;
}

It may be late too answer but i'll explain some things to you..
Array Size cannot be increase because of contiguous memory allocation in the memory.
For Example => The address of the every location is
arr[5] => [2001,2002,2003,2004,2005]
Now, The main problem is if you allocate it to arr[10] so, as we don't know the next location 2006 will be free .
because array need to be in contiguous so, we won't be able to allocate memory
From my Suggestions use Vector or use dynamic Memory allocation in Cpp
int *old = new int[5];
int *nw = new int[10];
for (size_t i = 0; i < sizeof(old); i++)
nw[i] = old[i];
delete []old;
old = nw;
nw = NULL;

#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p,*q;
int i;
p=(int *)malloc(5*sizeof(int));
p[0]=3;p[1]=5;p[2]=7;p[3]=9;p[4]=11;
q=(int *)malloc(10*sizeof(int));
for(i=0;i<5;i++)
q[i]=p[i];
free(p);
p=q;
q=NULL;
for(i=0;i<5;i++)
printf("%d \n",p[i]);
return 0;
}

Related

SIGSEGV error while declaring array without creating new int[size]

I tried to write code where i have to return the pointer pointing to the first element of array.
I tried using this:-
int *construct(int arr[],int n)
{
int size=(int)(ceil(log2(n)));
size=2*pow(2,size)-1;
int st[size];
for(int i=0;i<size;i++)
st[i]=INT_MAX;
constructUtil(arr,st,0,n-1,0);
int *pt=&st[0];
return pt;
}
This gave me error.
But when i declared the same array like this:
int *st=new int[size];
It executed successfully.
What is the difference between these two?
You can´t return a pointer to a local array in C. You have to use malloc to allocate the memory and generate a pointer to a memory region for your array. Now you can return the pointer and the memory stays valid:
#include <stdio.h>
#include <stdlib.h>
int* construct(int n);
int main()
{
int* ArrayPointer = construct(100);
printf("Address: %p", ArrayPointer);
for(int i = 0; i < 100; i++)
{
printf("%i\n\r", ArrayPointer[i]);
}
free(ArrayPointer);
return 0;
}
int* construct(int n)
{
int* array = (int*)malloc(n * sizeof(int));
for(int i = 0; i < n; i++)
{
array[i] = i;
}
return array;
}
The instruction new does something similar to the malloc function (not exactly the same). The key operation of new is to ask the OS for some free memory for dynamic allocation (like malloc but from another memory pool). See the difference between malloc and new here. Another option (without dynamic memory) is to declare a static array with a fixed size. So the compiler will reserve the memory and you can pass the address of this array to your function

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.

Doubling the Size of a C++ Array

The following snippet of code is my attempt to increase the size of an array by a factor of two. I am having several problems with it. Most importantly, should I be calling delete on my original array?
void enlarge(int *array, int* dbl int size) {
for (int i = 0; i < size; i++)
dbl[i] = array[i];
delete array;
array = dbl;
}
You have a few problems:
Modifying array only modifies the local copy of the pointer. You need to take a reference-to-pointer if you want the modification to be observed by the calling code.
You need to use delete[] when deleting things allocated with new[].
You attempt to copy too many items, and in so doing you overrun the original array.
void enlarge(int *& array, int size) {
// ^
// Use a reference to a pointer.
int *dbl = new int[size*2];
for (int i = 0; i < size; i++) {
// ^
// Iterate up to size, not size*2.
dbl[i] = array[i];
}
delete[] array;
// ^
// Use delete[], not delete.
array = dbl;
}
However, I would strongly suggest using std::vector<int> instead; it will automatically resize as necessary and this is completely transparent to you.
keyword double cannot be used as variable name, and previous array must be deleted before new allocation get assigned to same pointer, and loop should copy size no of items from prev array (not 2 * size)
void enlarge(int **array, int size) {
int *d = new int[size*2];
for (int i = 0; i < size; i++)
d[i] = *array[i];
delete [] *array;
*array = d;
}
if previous array was int *arr, and size is the currentsize of the array arr, call should be as: enlarge(&arr, size)

Pointer/Refer to an array?

Okay, I'm writing a program that will perform different functions on an array. If necessary, the array will need to change capacity. The instructions are:
Create an new array.
Copy the contents from the old array to the new.
Delete the old array.
This part is understand, but what I don´t understand is how to keep a reference to the array that the functions will work with. This is my code for creating a new array and move over the elements.
int newSize = m_size*2;
double *tempArray= new double[newSize];
for(int i=0; i<m_size-1; i++)
{
tempArray[i] = arr[i];
}
delete []arr;
for(int i=0; i<m_size-1; i++)
{
arr[i] = tempArray[i];
}
delete []tempArray;
}
All the other methods use arr so I would like to reference back to that. A pointer won´t work since it only points to the first element. How can I use my arr variable to refer to an array?
In C and C++ dynamic arrays are usually represented by a pointer to the first element and the number of elements. So I'm assuming the following declarations:
double *arr;
int m_size;
If by any chance you have arr decleared as a real array double arr[..], then you cannot do delete []arr nor change its size!
Then your code should be along the lines of:
int newSize = 2*m_size;
double *tempArray= new double[newSize];
for(int i=0; i<m_size-1; i++)
{
tempArray[i] = arr[i];
}
delete []arr;
arr = tempArray;
m_size = newSize;
But now I wonder: why m_size-1 in the loop?
And also, you can just do:
memcpy(tempArray, arr, sizeof(*arr) * m_size)); //or m_size-1?
All this is nice if it is an exercise. For real code it almost always better to use std::vector<double> and the resize() member function.
You got undefined behaviour in your code.
delete []arr;
for(int i=0; i<m_size-1; i++)
{
arr[i] = tempArray[i];
}
You delete the memory arr was pointing to and then assign to the deleted memory inside the loop. Instead you should just write:
delete []arr;
arr = tempArray;
The whole code would be:
int newSize = m_size*2;
double *tempArray= new double[newSize];
for(int i=0; i<m_size-1; i++) // -1 might be wrong, look below for a comment on this line.
{
tempArray[i] = arr[i];
}
delete []arr;
arr = tempArray;
m_size = newSize // stolen from the others *cough* since I oversaw the need.
// note that I don't call delete on tempArray.
}
Also I don't know how you allocated your first array but if you made it calling new double[m_size] then you'd want to delete the -1 in the loop condition of the for loop since you're checking for i < m_size and not i <= m_size.
You need to allocate memory for ar after deallocating it.
int newSize = m_size*2;
double *tempArray= new double[newSize];
for(int i=0; i<m_size-1; i++)
{
tempArray[i] = arr[i];
}
delete []arr;
ar = new double[newSize];
for(int i=0; i<m_size-1; i++)
{
arr[i] = tempArray[i];
}
delete []tempArray;
delete []arr;
for(int i=0; i<m_size-1; i++)
{
arr[i] = tempArray[i];
}
Oops. Don't access after delete. And don't delete unless it was allocated with new.
You simply can't reallocate an array declared as
int arr[100]
or similar.
Based on the code you've given, what you're currently performing is:
Create a new array (tempArray)
Copy the contents of the old (arr) array to the new (temp) - (note - what happens if you make the new array smaller than the old?)
Delete the old array
Copy the new values back into the deleted remains of the old array (note - you deleted arr so you can't use it now!)
Delete the new array (so everything is gone)
Basically, you need to fix step 2, to handle sizes, and get rid of steps 4 and 5 entirely - you just need to re-assign arr instead:
arr = tempArray
You just have to declare the array arr and put the values in it. You can refer to the array through its pointer arr or each element with arr[element_id].
You have a couple of options here:
Take the C-style approach of just storing the pointer to the first element like you have, plus the length. From those two you can calculate anything you need.
Use std::vector. It holds an array, allows you to easily resize it with functions like emplace_back, and can tell you its length with the size function.
The second approach is certainly preferred. If you're in C++, you should usually be using std::vector instead of raw arrays, unless you're looking for a fixed-sized one. In that case use std::array.
You also get the added benefit of copying a vector being as simple as vector1 = vector2;.

Deleting a Triple Pointer in c++

I have a triple pointer to an Object in C++ and I need to free the entire thing after use.
MyClass *** foobar = new MyClass **[10000];
How do I write the delete statement for this.
It depends on how you allocate the pointers-to-pointers. If you do:
int x;
int* p = &x;
int** pp = &p;
int*** ppp = &pp;
Then you don't have to delete anything.
On the other hand, if you do:
int* p = new int;
int** pp = &p;
int*** ppp = &pp;
Then you only have to delete p. For:
// i.e., allocate 1000 ints, return a pointer, and then get the address of that pointer
int** pp = &(new int[1000]);
// Oh, and get the address of the int**
int*** ppp = &pp;
You have to delete[] *pp (i.e., dereference pp to get the original pointer to the array of ints, and then delete[] the array).
How do you alloc it? Generally, if A is pointer to B, B is pointer to C and C is pointer to D (data), you need to free D, then C and B as the last one.
Anything you new[], you will have to delete[]. It's that simple.
If you do it at several levels, you will have to delete[] in the reverse order of the new[]'s.
If the only allocation that you have done is the one you show in the question, then you only need to do:
delete [] **foobar;
As that is the only memory that was actually acquired. If you have allocated memory to elements inside foobar, then you must clear them up in reverse order of creation.
Note that in most cases these types of structures can be simplified. For example, if the actual data to hold is a cube, you can allocate a single block of 1000*1000*1000 elements (that is a HUGE amount of them) and deallocate it with a single delete []. If you wrap the memory inside a class, then you can provide operator() that will map from three indices to the unique element in the sequential container. Take a look at the C++FAQ lite here.
3D memory allocation
int ***allocate3D(int ***mat, int k, int l, int m) {
mat = (int***) malloc( sizeof(int)*k*l*m );
for(int i=0;i<k;i++)
mat[i] = (int**) malloc ( sizeof(int)*l*m );
for(int i=0; i<k; i++) for(int j=0; j<l; j++)
mat[i][j] = (int*) malloc ( sizeof(int)*m );
return mat;
}
3D matrix deallocation:
void deAllocate3D(int ***mat, int k, int l, int m){
//Delete in reverse order of allocation
for(int i=0; i<k; i++) for(int j=0; j<l; j++) { free(mat[i][j]); mat[i][j] = NULL; }
for(int i=0; i<k; i++) { free(mat[i]); mat[i] = NULL; }
free(mat); mat = NULL;
}
Find the full source code here