The other day I saw the following code:
int main()
{
int *p; int tam;
cout << "Ingrese el tamaño" << endl;
cin >> tam;
p = new int[tam + 5];
p[0] = 67;
p[1] = 72;
p[2] = 15;
p[3] = 81;
p[4] = 23;
cout << *(p+2) << endl;
return 0;
}
And before the question:
"What is wrong with this program?"
I thought it wouldn't compile because p = new int[tam + 5]
it's not a valid expression. Especially for int[tam + 5]
.
However, I was wrong. The program compiles and what it does is display 15 on the console.
I replied: It doesn't compile. what is wrong
And now, although I understand why it shows 15, I can't find documentation or things to read about expressions like int[tam + 5]
. What happens in the compiler?
On the other hand, what is the use of these expressions? Are they really used?
PS: I think I should change the title to something more representative. Is this inside pointer arithmetic?
In this link you will be able to verify that in C++ the operator
new int[tam + 5]
is equivalent to the call in Ccalloc(tam + 5, sizeof(int))
. Both reserve memory fortam + 5
elements of typeint
. The equivalent of the callfree(..)
would be the operatordelete []
.Although the behavior is equivalent and you can use the
malloc()
,calloc()
,free()
, etc functions in C++, it is not recommended to mix both methods because each has its own set of functions and operators.What is the utility of these expressions? Are they really used?
Of course, it is the usual practice to create dynamic data sets (vectors, matrices, etc) from primitive data (such as
int
,float
, etc).Is this inside pointer arithmetic?
They are, after all, pointers, so it is equivalent, although the term "pointer arithmetic" is a bit confusing.
What happens in the compiler?
I'll try to explain it in comments:
In C++ there are two ways to call
new
:Simple reservations (a single element)
Array reservations (multiple elements)
On the other hand, note that the number of elements that the array will contain is indicated within the square brackets (data necessary for the system to know how many bytes of memory it needs). This size can be a default value at compile time:
But it can also be a value provided at runtime:
Because of this second feature, the size must be able to be evaluated at compile time, and for this reason there is no harm in having the size given by an equation:
What happens in these cases is that the expression indicating the number of elements will be evaluated first, and then a function call will be executed in
new
order to allocate the necessary memory.Then, as you can see, the expression you comment is totally valid.
Nothing out of this world happens. The compiler comes across a call to allocate an array of elements and simply makes that call.
This call serves to reserve arrays for an indeterminate number of elements. No more no less.
The truth is that yes.
Dynamic memory reservation is quite a slow process as it involves a series of operations that can be quite heavy.
If you know that you are going to have to manage a collection of
x
elements, it is much faster to request a single reservation to store those elements than to makex
individual reservations... besides, with this practice the memory will suffer less fragmentation and that will make the machine slow down even less (and eventually run out of memory despite having free memory).Another advantage over individual reservations is that memory management is greatly simplified. It is not the same to free the memory with a single one
delete[]
than to have to program a loop that manages multiple deletions... the possibilities of leaving memory without freeing in this second case are greater.But of course, this feature cannot always be used (for example, if each object has its own life cycle or if the list can grow over time... but if this solution is applicable to a problem, it will certainly be faster than walking Managing individual reservations.
On the other hand, that the size of the reserve is given by a function or an expression is not difficult to find. A buffer used for compression may have a size whose value is based on applying logarithms to the size of the plain text...
No, it couldn't be considered pointer arithmetic. This tag might be applicable if the program had done something like this:
Which is the same as what you are doing right now but applying pointer arithmetic. C++ gives to write many books...