Hỏi về phạm vi của con trỏ

tui mới học c++ được một khoảng thời gian nên cũng chưa rõ lắm, mọi người cho tui hỏi về câu lệnh dưới đây

#include <iostream>
using namespace std;
int main()
{ 

{int *p;
cout << p<< endl;} // lệnh cout 1


cout << p<< endl;  // lệnh cout 2
system("pause");
	return 0;
}

tui khai báo một biến con trỏ và đặt nó trong phần {} của ‘lệnh cout 1’, theo tui biết thì khi khai báo một biến con trỏ thì nó sẽ khai báo trong vùng nhớ heap nên CPU không tự xóa được, vậy có nghĩa là khi ra khỏi dấu {} của ‘lệnh cout 1’ con trỏ p vẫn còn tồn tại, vậy sao khi tui in ra địa chỉ của nó tại ‘lệnh cout 2’ thì chương trình lại báo không hiểu p là gì, mọi người có thể giải thích giùm tui không

Không đúng. *p chỉ hiện diện trong scope, nơi nó trỏ đến (vẫn chưa xác định) thì có thể còn, nhưng nếu chưa chép ra cái gì ngoài scope thì coi như mất.

2 Likes

bạn có thể giải thích kỹ hơn không, mình chưa hiểu lắm

khi viết int* p; thì p là con trỏ chứa địa chỉ nào đó ko xác định và p nằm trên stack. Địa chỉ nó trỏ tới có thể là địa chỉ thuộc stack hoặc heap. Làm gì có “khai báo con trỏ thì nó sẽ khai báo vùng nhớ heap” :V :V

vd viết

int a = 10;
int* p = &a;

thì p có trỏ tới vùng nhớ nào trên heap đâu, nó trỏ tới a là biến nằm trên stack tức là nó trỏ tới vùng nhớ trên stack mà :V Trên stack lúc này có 2 biến là a (kiểu số nguyên - có thể chiếm 4 bytes trong stack) và p (kiểu con trỏ - có thể chiếm 8 bytes trong stack)

viết

int* p = new int;

thì p mới trỏ tới vùng nhớ có kích thước là sizeof(int) (có thể là 4 bytes) nằm trên heap. Trên stack lúc này chứa 1 biến p có kiểu là con trỏ, kích thước p có thể là 8 bytes.

nếu viết

{ int* p = new int; }
std::cout << p; // ko biên dịch được

thì trình dịch ko biên dịch được vì sau dấu } p đã bị đẩy ra khỏi stack rồi. Ở đây mình viết là p bị “đẩy” ra khỏi stack để tránh hiểu nhầm với p bị “xóa”, dễ hiểu lầm là vùng nhớ mà p trỏ tới cũng bị xóa, ở đây chỉ có p bị đẩy ra khỏi stack, còn vùng nhớ được cấp phát bằng new int vẫn còn trên heap, nhưng ko còn biết nó ở đâu nữa vì con trỏ p chứa địa chỉ của nó đã bị đẩy ra khỏi stack. Cái này gọi là memory leak :V

4 Likes

p khai báo trong { } thì cái phạm vi truy cập của nó chỉ tính trong cái { } đó và phía dưới lệnh khai báo p.
Đó là xét về mặt code.

Còn mặt hoạt động thì cái “khai báo trên heap thì CPU không tự xóa được” thì chính xác hiểu là khi cấp phát động bộ nhớ bằng new thì nó sinh ra 2 thứ là bộ nhớ được cấp phát (M) trên heap và con P trỏ trỏ tới M nằm trên stack.
P thì được thu hồi tự động khi ra khỏi { } nhưng M thì không. M được thu hồi khi gọi delete, delete[] hoặc khi kết thúc chương trình.

3 Likes

à, mình hiểu rồi, vậy mà đó giờ cứ hiểu nhầm

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?