Array parsing in C++ is always done by reference, and in std there's no concept of parsing by value. From a stakoverflow question I summarize this below. The array size information is lost here.
void by_pointer(int *p, int size);
void by_pointer(int p[], int size);
void by_pointer(int p[7], int size); // the 7 is ignored in this context!
void by_reference(int (&a)[7]); // only arrays of size 7 can be passed here!
template void by_reference(int (&a)[size]);
void TestMethod(char cArray[], int size) {
const char* pTest = "test";
strncpy(cArray, pTest, size);
cArray[ size-1] = '\0';
}
Usage:
char cMyArray[7] = {a};
TestMethod(cMyAray, 7}
However this can be quite tricky to understand. Take the problem of dynamic resizing of an array.
unsigned int iArrSize = 10;
int *iArr = new int[iArrSize];
for (int i = 0; i < 100; i++) {
if (i >= iArrSize) {
int *arr3 = new int[iArrSize*2];
memcpy(arr3, iArr, iArrSize * sizeof (int));
delete[] iArr;
iArr = arr3;
iArrSize = iArrSize*2;
}
iArr[i] = i;
}
for (int i = 0; i < 100; i++) {
std::cout << iArr[i] << std::endl;
}
delete[] iArr;
This works just fine. Now try to replace the array resizing part with a function.......
unsigned int iArrSize = 10;
int *iArr = new int[iArrSize];
for (int i = 0; i < 100; i++) {
if (i >= iArrSize) {
EnlargeArray(iArr, iArrSize);
iArrSize = iArrSize*2;
}
iArr[i] = i;
}
for (int i = 0; i < 100; i++) {
std::cout << iArr[i] << std::endl;
}
delete[] iArr;
void EnlargeArray(int* arr, unsigned int arr_size) {
int *arr3 = new int[arr_size*2];
memcpy(arr3, arr, arr_size * sizeof (int));
delete[] arr;
arr = arr3;
}
This will lead to a segmentation fault and using valgrind would say that the line iArr[i] = i; is trying to use already deleted memory at delete[] arr in side the EnlargeArray(). Why?
The parameter arr will point to the start of the real array iArr, this is TRUE
So deleting this will delete the real array.
However we we say arr = arr3; I expected the real array to be set the start of the newly allocated array arr3, which is FALSE
This is because the parameter name is not passed by reference, but what gets passed is actually a copy of the pointer, so when you assign something to it, the copy gets updated but not the original !!!
So you'd have to go with,
void EnlargeArray(int* & arr, unsigned int arr_size)or void EnlargeArray(int** arr, unsigned int arr_size)
void by_pointer(int *p, int size);
void by_pointer(int p[], int size);
void by_pointer(int p[7], int size); // the 7 is ignored in this context!
void by_reference(int (&a)[7]); // only arrays of size 7 can be passed here!
template
strncpy(cArray, pTest,
cArray[
}
int *iArr = new int[iArrSize];
for (int i = 0; i < 100; i++) {
if (i >= iArrSize) {
int *arr3 = new int[iArrSize*2];
memcpy(arr3, iArr, iArrSize * sizeof (int));
delete[] iArr;
iArr = arr3;
iArrSize = iArrSize*2;
}
iArr[i] = i;
}
for (int i = 0; i < 100; i++) {
std::cout << iArr[i] << std::endl;
}
delete[] iArr;
int *iArr = new int[iArrSize];
for (int i = 0; i < 100; i++) {
if (i >= iArrSize) {
EnlargeArray(iArr, iArrSize);
iArrSize = iArrSize*2;
}
iArr[i] = i;
}
for (int i = 0; i < 100; i++) {
std::cout << iArr[i] << std::endl;
}
delete[] iArr;
int *arr3 = new int[arr_size*2];
memcpy(arr3, arr, arr_size * sizeof (int));
delete[] arr;
arr = arr3;
}
The parameter arr will point to the start of the real array iArr, this is TRUE
So deleting this will delete the real array.
However we we say arr = arr3; I expected the real array to be set the start of the newly allocated array arr3, which is FALSE
This is because the parameter name is not passed by reference, but what gets passed is actually a copy of the pointer, so when you assign something to it, the copy gets updated but not the original !!!
So you'd have to go with,
void EnlargeArray(int* & arr, unsigned int arr_size)
Comments
Post a Comment