1. Vấn đề với cấp phát bộ nhớ động
Khi hàm gọi xong thì con trỏ trong hàm cũng không còn, tham chiếu đến bộ nhớ được cấp cũng không còn, dẫn đến Memory Leak .
Memory Leak (rò rỉ bộ nhớ) cũng xảy ra khi ta gán con trỏ đến địa chỉ mới :
1
2
| int *pnValue = new int ; pnValue = new int ; // old address lost, memory leak results
|
1
2
3
| int nValue = 5; int *pnValue = new int ; pnValue = &nValue; // old address lost, memory leak results
|
1
2
| int *pnValue = new int ; int *pnOtherValue = 0; // will allocate later |
1
2
3
4
5
6
7
| int *pnValue = new int ; *pnValue = 7; delete pnValue; pnValue = 0; if (pnValue) *pnValue = 5; |
2. Con trỏ hằng :
Một con trỏ hằng khai báo như sau :
int
*
const
pnPtr;
Lưu ý : Phân biệt
int
*
const
pnPtr = &value (con trỏ hằng - địa chỉ nó trỏ đến không thể thay đổi)
const
int
*pnPtr =
&value (con trỏ này trỏ đến 1 hằng số - và giá trị của con trỏ là không thể thay đổi)
Cụ thể là :
- Con trỏ hằng không thể thay đổi địa chỉ mà nó đã trỏ vào nhưng thay đổi được giá trị của nó :
1
2
| int nValue = 5; int * const pnPtr = &nValue; |
Khi đó :
int
nValue2 = 6 (khai báo 1 biến Integer có địa chỉ khác với địa chỉ của pnPtr)
pnPtr = &nValue (không được phép)
*
pnPtr = nValue2 (được phép)
- Con trỏ mà trỏ vào 1 hằng số thì không thể thay đổi trực tiếp giá trị của con trỏ nhưng địa chỉ thì thay đổi được (và tất nhiên khi bạn thay đổi địa chỉ thì khi đó giá trị của con trỏ sẽ thay đổi theo địa chỉ mới) :
1
2
| int nValue = 5; const int *pnPtr = &nValue;
|
Khi đó :
*
pnPtr = nValue2 (không được phép) pnPtr = &nValue (được phép)
- Và tất nhiên là khi khai báo như thế này thì cả địa chỉ lẫn giá trị của con trỏ là không thể thay đổi : Con trỏ hằng trỏ vào 1 hằng số :
const
int
*
const
pnPtr = &nValue;
3. Tham chiếu và con trỏ rỗng :
1
2
3
| int nValue = 5; int * const pnValue = &nValue; int &rnValue = nValue; |
Khi đó rnValue = *pnValue = 5, rnValue là tham chiếu đến địa chỉ nValue = 5.
Con trỏ rỗng : Ta phải dùng cách ép kiểu nếu muốn truy xuất giá trị từ pVoid (bằng cách sử dụng một con trỏ Integer khác là pInt)
1
2
3
4
5
6
7
8
| int nValue = 5; void *pVoid = &nValue; // can not dereference pVoid because it is a void pointer int *pInt = static_cast < int *>(pVoid); // cast from void* to int* cout << *pInt << endl; // can dereference pInt |
Theo nguồn : http://www.learncpp.com/cpp-tutorial/69-dynamic-memory-allocation-with-new-and-delete/