Dynamic allocation to array of pointers and its alternatives - c++

The standard way of allocating array using new int is:
int* arr = new int[50];
while declaring it in this manner there is going to be contiguous memory allocation and there will be a single array variable in the stack of variables.
if I want to declare it in the form of 50 different pointer variables so that each pointer would have different memory address and not necessarily contiguous the most obvious way of going for it is like this:
int * arr[50];
but in this way what would be the command / code for assigning memory ( i.e. via new int ) and what are the downsides or advantages of declaring in each manner.

The obvious way would be to iterate over all the elements and allocate memory for them:
for (int i = 0; i < 50; i++){
arr[i] = new int;
}
The downside of non-contiguous memory chunk would be cache misses.
You can read more on that here.

How to assign, is already mentioned in this answer; Hence not repeating.
For single int allocation, your below line is an overkill:
int* arr[50]; // all downsides only
Instead of that, you should use simple integers:
int arr[50];
Better to utilise facilities by standard containers such as:
std::vector<int> vi; // if the number of int-s are dynamic
std::array<int, 50> ai; // if the number of int-s are fixed
Finally, from this answer,
"Avoid pointers until you can't... So the rule of thumb is to use pointers only if there is no other choice."

Related

different between int **arr =new int [ n]; and int a[i][j]?

I was solving a problem on sum of submatrices, I declared my 2d-array as
int a[i][j] ; //i =number of rows and j = number of columns
my code executed properly. But when I saw the solution
i saw these lines :
int **arr = new int * [n] ;
for (int i = 0 ; i < n ; i++)
{
arr[i]=new int [m];
}
// n -> number of rows and m -> number of columns.
I understand the code. why the solution(given on some random website) is using pointers. If we can do it using the above normal declaration. It will make the code faster or something?
This declaration
int a[i][j] ; //i =number of rows and j = number of columns
requires that the variables i and j would be compile-time constants. Variable length arrays is not a standard C++n feature though some compilers can have their own language extensions that include this feature.
The second problem that exists is if sizes of an array are too big then the compiler can be unable to create such an array with automatic storage duration.
So if i and j are not compile-time constants or are too big then you have to allocated memory dynamically yourself or you can use the standard container std::vector.
If we can do it using the above normal declaration. It will make the code faster or something?
no all in above code you create an array in the stack it will be deleted if the function out of scope it will be removed automatically
the second is created in heap it will still in the heap until u delete it by self
Both ways of array declaration are useful in different use cases. The declaration:
int a[i][j];
declares an array statically and it uses stack memory to store the array or we can say that the memory is allocated at the runtime. This type of array declaration requires you to pass the value 'n' and the size of the array can not be altered after it's been declared. That's where it has a drawback as you can not increase the size if you want to store some more elements. Also if you stored less elements than 'n', then the remaining memory gets wasted.
The other type of declaration:
int *a = new int[n]; //For 1D array
creates a dynamically allocated memory. In other words, in this type of declaration memory allocation takes place only when an element is placed in the array or at the runtime.
This allocation ensures that there is no memory wastage and stores the elements of the array in the heap memory. But in this type of declaration, you also need to deallocate the memory otherwise it may cause memory leaks because C++ has nothing like a garbage collector.

Should I use vectors instead of arrays?

If I have a fixed number of elements of class MyClass, should I use arrays or vectors?, ie:
MyClass* myArray[];
or
std::vector<MyClass*> myVector;
?
Use std::array or raw arrays for a small, static number of elements.
If you have a lot of elements (more than say 100kb), you hog the stack and are asking for stack corruption / overflow. In that case, or if the number of elements can only be known at runtime, use std::vector.
if you know the number in compile time - use static array.
if the number is dynamic (obtained from the user) - vector is much better to save you the hurdle of managing the memory
"Fixed" has two meanings in this context. The usual one is set once, never change, such as a value read from input. This value is known at runtime and requires dynamic allocation on the heap. Your options are a C-style array with new or a vector; it is highly recommended you use a vector.
#include <vector>
#include <iostream>
int main() {
int size;
std::cin >> size;
int *myArray = new int[size];
std::vector<int> myVector(size);
}
"Fixed" can also mean a compile-time constant, meaning it is constant for any run of the program. You can use a C-style array or a C++ array (automatic memory allocation on the stack).
#include <array>
int main() {
const int size = 50;
int myArray[size];
std::array<int, size> myArray;
}
These are faster, but your program needs to have access to sufficient stack memory, which is something you can change in your project settings. See this topic for more info. If the size of the array is really big, you may want to consider allocating on the Heap anyway (vector).

How can we modify the size of array in C++?

I have an array of characters allocated with new and i want to modify the size of the array. Can i use realloc function for that? What is the best way to do so?
No, you can't... realloc() can only be used with malloc()/free()
Best call for a new[] allocated array is to create a new one and then memcpy() the data from one to another.
Better way - use an std::vector or std::string instead of array if you know you'll need resizing. Internally they're pretty much the same array.
In C++ it is best to use the STL std::vector class for this kind of thing. Either that, or a std::string.
I have an array of characters allocated with new and i want to modify the size of the array.
You can't resize an array, you can only allocate a new, larger one, move the contents to the new array, and delete the old one.
Can i use realloc function for that?
If you used malloc to allocate the original array, yes. But that's usually a bad idea in C++, where you usually want to deal with arrays of non-trivial objects not raw memory.
What is the best way to do so?
Use std::string (or perhaps std::vector<char>) to manage a dynamic array of characters automatically. These also have the advantage of using RAII to reduce the risk of memory leaks and other memory management errors.
You can use realloc(), if your array is allocated dynamically(via malloc/calloc/realloc). If you have static array, you can't resize it.If you have allocated with new:
int* Copy = new int[newSize];
std::copy(oldCopy,oldCopy+size,Copy);
But the best way would be to use std::vector<type> from c++ standard library
As was said by others, you cannot resize the array that was allocated per se, but you can create a larger one, copy the content of the first array to the second and delete the first one.
Here's an example, using std::copy().
int main(int argc, char** argv) {
int* arr = new int[5];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
arr[4] = 5;
int* tmp = new int[10];
std::copy(arr, arr + 5, tmp);
std::copy(arr, arr, tmp + 5);
delete[] arr;
arr = tmp;
for(int i = 0; i < 10; i++) {
std::cout << arr[i] << "\n";
}
delete[] arr;
std::cin.get();
return 0;
}
This first creates an integer array and fills it. It then creates a larger array and fills it with the content of the first array twice and display that new larger array.
The principle is the same for an array of characters.
As the others have mentionned, your best bet in C++ is to use the standard library. For a resizable array of characters, you should probably use std::string or a vector of strings, but it's a bit overkill in some situations.

how to allocate dynamic memory to int a[4][3] array

how to allocate run time memory to an array of size[4][3]?
i.e int a[4][3]
If need is to allocate memory to an array at run time than how to allocate memory to 2D array or 3D array.
Editing the answer based on comments. Allocate separately for each dimension. For a 2D array a 2 level allocation is required.
*a = (int**)malloc(numberOfRows*sizeof(int*));
for(int i=0; i<numberOfRows; i++)
{
(*arr)[i] = (int*)malloc(numberOfColumns*sizeof(int));
}
The simplest way to allocate dynamically an array of type int[4][3] is the following
int ( *a )[3] = new int[4][3];
// some stuff using the array
delete []a;
Another way is to allocate several arrays. For example
int **a = new int * [4];
for ( size_t i = 0; i < 4; i++ ) a[i] = new int[3];
// some stuff using the array
for ( size_t i = 0; i < 4; i++ ) delete []a[i];
delete []a;
What have you tried. new int[4][3] is a perfectly valid
expression, and the results can be assigned to a variable with the
appropriate type:
int (*array2D)[3] = new int[4][3];
Having said that: I can't really think of a case where this
would be appropriate. Practically speaking, anytime you need
a 2 dimensional array, you should define a class which
implements it (using std::vector<int> for the actual memory).
A pure C approach is the following:
int (*size)[4][3];
size = malloc(sizeof *size);
/* Verify size is not NULL */
/* Example of access */
(*size)[1][2] = 89;
/* Do something useful */
/* Deallocate */
free(size);
The benefit is that you consume less memory by not allocating intermediate pointers, you deal with a single block of memory and deallocation is simpler. This is especially important if you start to have more than 2 dimensions.
The drawback is that the access syntax is more complicated, as you need to dereference a pointer before being able to index.
Use calloc, i guess this will do.
int **p;
p=(int**)calloc(4,sizeof(int));
In C you can use pointer to pointer
AS #Lundin mentioned this is not 2D array. It is a lookup table using pointers to fragmented memory areas allocated all over the heap.
You need to allocate how many pointers you need and then allocate each pointer. you can allocate fixed size or varaible size depending on your requirement
//step-1: pointer to row
int **a = malloc(sizeof(int *) * MAX_NUMBER_OF_POINTERS);
//step-2: for each rows
for(i = 0; i < MAX_NUMBER_OF_POINTERS; i++){
//if you want to allocate variable sizes read them here
a[i] = malloc(sizeof(int) * MAX_SIZE_FOR_EACH_POINTER); // where as if you use character pointer always allocate one byte extra for null character
}
Where as if you want to allocate char pointers avoid using sizeof(char) inside for loop. because sizeof(char) == 1 and do not cast malloc result.
see How to declare a 2d array in C++ using new
You could use std::vector<> since it is a templated container (meaning array elements can be whatever type you need). std::vector<> allows for dynamic memory usage (you can change the size of the vector<> whenever you need to..the memory is allocated and free'd automatically).
For example:
#include <iostream>
#include <vector>
using namespace std; // saves you from having to write std:: in front of everthing
int main()
{
vector<int> vA;
vA.resize(4*3); // allocate memory for 12 elements
// Or, if you prefer working with arrays of arrays (vectors of vectors)
vector<vector<int> > vB;
vB.resize(4);
for (int i = 0; i < vB.size(); ++i)
vB[i].resize(3);
// Now you can access the elements the same as you would for an array
cout << "The last element is " << vB[3][2] << endl;
}
You can use malloc() in c or new in c++ for dynamic memory allocation.

Pointer to an array get size C++

int * a;
a = new int[10];
cout << sizeof(a)/sizeof(int);
if i would use a normal array the answer would be 10,
alas, the lucky number printed was 1, because sizeof(int) is 4 and iszeof(*int) is 4 too. How do i owercome this? In my case keeping size in memory is a complicated option. How do i get size using code?
My best guess would be to iterate through an array and search for it's end, and the end is 0, right? Any suggestions?
--edit
well, what i fear about vectors is that it will reallocate while pushing back, well you got the point, i can jus allocate the memory. Hoever i cant change the stucture, the whole code is releevant. Thanks for the answers, i see there's no way around, so ill just look for a way to store the size in memory.
what i asked whas not what kind of structure to use.
Simple.
Use std::vector<int> Or std::array<int, N> (where N is a compile-time constant).
If you know the size of your array at compile time, and it doens't need to grow at runtime, then use std::array. Else use std::vector.
These are called sequence-container classes which define a member function called size() which returns the number of elements in the container. You can use that whenever you need to know the size. :-)
Read the documentation:
std::array with example
std::vector with example
When you use std::vector, you should consider using reserve() if you've some vague idea of the number of elements the container is going to hold. That will give you performance benefit.
If you worry about performance of std::vector vs raw-arrays, then read the accepted answer here:
Is std::vector so much slower than plain arrays?
It explains why the code in the question is slow, which has nothing to do with std::vector itself, rather its incorrect usage.
If you cannot use either of them, and are forced to use int*, then I would suggest these two alternatives. Choose whatever suits your need.
struct array
{
int *elements; //elements
size_t size; //number of elements
};
That is self-explanatory.
The second one is this: allocate memory for one more element and store the size in the first element as:
int N = howManyElements();
int *array = int new[N+1]; //allocate memory for size storage also!
array[0] = N; //store N in the first element!
//your code : iterate i=1 to i<=N
//must delete it once done
delete []array;
sizeof(a) is going to be the size of the pointer, not the size of the allocated array.
There is no way to get the size of the array after you've allocated it. The sizeof operator has to be able to be evaluated at compile time.
How would the compiler know how big the array was in this function?
void foo(int size)
{
int * a;
a = new int[size];
cout << sizeof(a)/sizeof(int);
delete[] a;
}
It couldn't. So it's not possible for the sizeof operator to return the size of an allocated array. And, in fact, there is no reliable way to get the size of an array you've allocated with new. Let me repeat this there is no reliable way to get the size of an array you've allocated with new. You have to store the size someplace.
Luckily, this problem has already been solved for you, and it's guaranteed to be there in any implementation of C++. If you want a nice array that stores the size along with the array, use ::std::vector. Particularly if you're using new to allocate your array.
#include <vector>
void foo(int size)
{
::std::vector<int> a(size);
cout << a.size();
}
There you go. Notice how you no longer have to remember to delete it. As a further note, using ::std::vector in this way has no performance penalty over using new in the way you were using it.
If you are unable to use std::vector and std::array as you have stated, than your only remaning option is to keep track of the size of the array yourself.
I still suspect that your reasons for avoiding std::vector are misguided. Even for performance monitoring software, intelligent uses of vector are reasonable. If you are concerned about resizing you can preallocate the vector to be reasonably large.