I wanted to create an array of a certain class but its size was not determined until run time. Therefore I had to of course use a pointer. Now because it was always good practice to initialize a pointer to NULL, I did so and I passed this initialized pointer to a function. This function would then new the pointer inside, seemed OK but this made the program crash.
I used the function AllocateArray1in the gist. Why did it crash?
The pointer is passed by value and when the function exits the pointer being passed is not quite initialized.
To verify this I used the test case 3 where I created an array, deleted it but didn't assign it back to NULL, this made sure that the pointer is still pointed to a certain memory address.
The works because although the memory is deallocated we can still access the values using raw pointers, although this might crash some times due to access violation.
The other option of course, which I used was to pass the pointer by reference. AllocateArray2 ensures that the same memory address is passed.
I used the function AllocateArray1in the gist. Why did it crash?
The pointer is passed by value and when the function exits the pointer being passed is not quite initialized.
To verify this I used the test case 3 where I created an array, deleted it but didn't assign it back to NULL, this made sure that the pointer is still pointed to a certain memory address.
The works because although the memory is deallocated we can still access the values using raw pointers, although this might crash some times due to access violation.
The other option of course, which I used was to pass the pointer by reference. AllocateArray2 ensures that the same memory address is passed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
using namespace std; | |
class MyClass { | |
public: | |
int iMyVar; | |
}; | |
void AllocateArray1(MyClass* pMyClassPointer) { | |
std::cout << "Function 1 called" << std::endl; | |
pMyClassPointer = new MyClass[10]; | |
for (int i = 0; i < 10; i++) | |
pMyClassPointer[i].iMyVar = i; | |
} | |
void AllocateArray2(MyClass* & rpMyClassPointer) { | |
std::cout << "Function 2 called" << std::endl; | |
rpMyClassPointer = new MyClass[10]; | |
for (int i = 0; i < 10; i++) | |
rpMyClassPointer[i].iMyVar = i; | |
} | |
void DontAllocateArray1(MyClass* pMyClassPointer) { | |
std::cout << "Function 3 called" << std::endl; | |
for (int i = 0; i < 10; i++) | |
std::cout << pMyClassPointer[i].iMyVar << std::endl; | |
} | |
void DontAllocateArray2(MyClass* & pMyClassPointer) { | |
std::cout << "Function 4 called" << std::endl; | |
for (int i = 0; i < 10; i++) | |
std::cout << pMyClassPointer[i].iMyVar << std::endl; | |
} | |
int main(int argc, char** argv) { | |
// use only 1 test case | |
MyClass *pPointer = NULL; | |
// test case 1 | |
AllocateArray1(pPointer); // sgementation fault | |
// test case 2 | |
AllocateArray2(pPointer); // works | |
// test case 3 // works | |
pPointer = new MyClass[10]; | |
delete pPointer; | |
AllocateArray1(pPointer); | |
// test case 4 | |
pPointer = new MyClass[10]; | |
DontAllocateArray1(pPointer); // works | |
// test case 5 | |
pPointer = new MyClass[10]; | |
DontAllocateArray2(pPointer); // works | |
// this shsould always be there | |
for (int i = 0; i < 10; i++) | |
std::cout << pPointer[i].iMyVar << std::endl; | |
} | |
Comments
Post a Comment