I am new to C++ programming and want to try out manual memory management (I am aware that it is advised not to use manual memory management, but I still want to give it a try).
My goal was to write a function that can append an element to an array by using realloc.
I use this struct:
struct pathToCity{
int lengthCities;
char cities[100];
};
Here is my function:
void appendToPathToCitiesArray(pathToCity **array, int *length, pathToCity newCity) {
if (*length == 0) {
*array = (pathToCity*) malloc(sizeof(pathToCity));
}
else {
*array = (pathToCity*) realloc(*array, (*length + 1) * sizeof(pathToCity));
}
if (array == NULL) {
cout << "Error allocating memory." << endl;
exit(-1);
}
(*array)[*length] = newCity;
(*length)++;
}
Here I define an array:
int lengthQueue = 0;
pathToCity *queue;
Here I instantiate an instance of my struct:
pathToCity newPath = {0, ""};
Finally I use my function:
appendToPathToCitiesArray(&queue, &lengthQueue, newPath);
This function works fine as it is using double pointers. According to my research (unfortunately I cannot find the stackoverflow post where this was explained) double pointers here are necessary, because once a pointer gets passed to a function, it is impossible to change the pointer inside the function. Therefore double pointers are required once I want to use realloc to update my array.
But I have also tried this in a different file:
#include <iostream>
using namespace std;
struct shortText {
int lengthText;
char text[3];
};
void append(shortText *array, int *length, shortText newCity) {
if (*length == 0) {
array = (shortText*) malloc(sizeof(shortText));
}
else {
array = (shortText*) realloc(array, (*length + 1) * sizeof(shortText));
}
if (array == NULL) {
cout << "Error allocating memory" << endl;
exit(-1);
}
array[*length] = newCity;
(*length)++;
}
int main() {
int length = 3;
shortText *arr = (shortText*) malloc(sizeof(shortText) * length);
arr[0] = {2, "ab"};
arr[1] = {2, "ab"};
arr[2] = {2, "ab"};
shortText s = {2, "ab"};
append(arr, &length, s);
arr[3] = {8, "ji"};
cout << length << endl;
cout << arr[3].lengthText << endl;
free(arr);
}
It also works perfectly and does not use double pointers. Why are double pointers necessary in one case and why not in the other?
If you require any more information, please ask. I have not provided the entire first code, to give a better overview, if I have missed out an important part, I will post the rest of the code.
Using the second function implementation invokes undefined behavior.
It just occurred such a way that the called function
reallocdid not change the address stored in the pointerarr. That is the function just enlarged the initial extent of memory. But in general it can allocate another extent of memory at a different address. In this case the pointerarrdeclared inmainwill be invalid.You need to pass a pointer to pointer because dereferencing the pointer to pointer you get a direct access to the original pointer
arrand thus can change it within the function. Otherwise the function will deal with a copy of the value of the original pointer and changing the copy will not influence on the original pointer.It is the so-called pass by reference in the C meaning.
Compare these two demonstration program.
and
There is used the typedef intentially
to show that instead of the type
intthere can be used also a pointer type as for exampleint *Only in main you should write
and call the function
fin the both demonstration programs.In C++ you could just pass the pointer by reference like
Pay attention to that this call of realloc
is unsafe and can result in a memory leak if the function will be unable to allocate a new extent of memory and will return a null pointer. You should use an intermediate pointer as for example