Hướng dẫn check cấp phát con trỏ

Trước tiên,tôi xin cung cấp link sau.Đây là bài viết rất rõ ràng của tác giả langman trên congdongcviet.Tôi nghĩ xem hết loạt kiến thức đó là quá đủ để hiểu về con trỏ rồi.Tuy nhiên,ở bài viết này.Tôi cũng muốn trình bày lại 1 ít kiếnthức cơ bản về con trỏ để các bạn dễ nhìn nhận vấn đề.và hơn nữa,nó cũng mạch lạc với loạt bài tôi viết.

link bài viết của langman -congdongcviet.com

//diendan.congdongcviet.com/showthread.php?t=42977

Các vấn đề được đưa ra

1/ con trỏ là gì

2/ tại sao lại phải dùng con trỏ

3/ con trỏ hàm,lớp …

4/ cấp phát và giải phóng bộ nhớ

5/ toán tử new và delete

Phần 1 ,2,3:

Khái niệm về con trỏ:

Con trỏ thực chất chỉ là 1 biến nguyên,nó mang giá trị của ô nhớ mà nó trỏ đến.

Như vậy.Dù được sử dụng như thế nào đi nữa,thì nó cũng chỉ là 1 biến nguyên.Trên các hệ thống 32bit nó có độ dài là 4byte.Vì sao lại là 4byte.Vì khi 1 vùng nhớ ảo cho mỡi tiến trình [đã trình bày ở chương 1].Thì chỉ cần 4byte là đủ đánh địa chỉ cho tất cả các ô nhớ ảo rồi.

Công dụng của nó thì cứ làm đi,sử dụng nó đi rồi biết.

khai báo :

Code:

int *p;

char * q;

float * h;

Gán ô nhớ cho con trỏ trỏ đến.

Ta sẽ xét trường hợp trên,thử printf ra xem sao :

Code:

printf["%d /n %p /n %p /n %d /n %p /n ",a,&a,p,*p,&p];

Ta build ở chế độ debug,không cần optimize,chỉ để hiểu thôi

Kết quả :

20

0032F9E8

0032F9E8

20

0032F9DC

Ta có thể thấy rằng

20 là giá trị của biến a,tại ô nhớ của biến a[ô nhớ này được đánh số 0032F9E8 tức là 0032F9DC]

ô nhớ chứa con trỏ p đánh giá trị 0032:F9DC và có giá trị là 0032F9DC

ta chỉ cần dùng *p là có thể lấy được giá trị của a;

Con trỏ đa cấp

Là loại con trỏ .. trỏ đến con trỏ.Thật dễ hiểu phải không !!

Code:

int a=2;

int **q=&p;

int * p = &a;

printf[“%d – %d -%p -%d -%d -%p \n”,p,*p,&p,max,*max,&max];

Con trỏ void

Là con trỏ đặc biệt,thích trỏ đi đâu trỏ.Có thể trỏ đến 1 vùng nhớ mang kiểu int,char …

Gán địa chỉ cho con trỏ :

Con trỏ hàm :

vâng, hàm vẫn cứ làm theo nguyên tắc 1 và 1 bản sao của con trỏ được tạo ra, và hàm làm việc với bản sao hàm, và trước khi gọi hàm con trỏ trỏ vào đâu thì nó vẫn được trỏ vào đấy chứng minh :

Code:

`

include `

include

int ham[int *a]

{

*a=2;

a++;

}

void main[]

{

int *a;

printf[“Truoc : %x”,a]; //trước và sau khi gọi hàm

ham[a]; //con trỏ a trỏ vào đâu

printf[“Sau %x”,a]; // thì nó vẫn trỏ vào đó

getch[];

}

hoạt động của 1 hàm :

1 hàm khi được biên dịch sẽ được compoler chừa ra 1 local_size nằm trên 1 vùng nhớ xác định trong không gian virtual memory của mõi tiến trình

Tùy vào kiểu calling convention mà localsize là bao nhiêu.Tôi sẽ trình bày phần này ở chương về PE file và các load của windows loader.Phần này không đi vào trình bày sâu.Bạn chỉ cần biết rằng.1 hàm khi biên dịch đều có 1 local size và đầu 1 hàm là 1 địa chỉ nhất định.

Ví dụ sau sẽ cho bạn thấy :

PHP Code:

int test[int foo]{ return foo; } int main[int argc,char* argv[]] { int [*adr][int]; int [*p][int]; p = test; adr = test; `int c = [ int] adr; p = [int[*][int]]c; // c là địa chỉ của hàm test //thực thi : // printf["%d",p[2]];`return

0; }

Qua ví dụ trên ta thấy,ta chỉ cần trỏ con trỏ p vào địa chỉ chứa hàm là có thể gọi thực thi từ địa chỉ cụ thể trên memory là c.Đó chính là cách hoạt động của con trỏ hàm.

Con trỏ trỏ đến class :

thật đơn giản.Con trỏ trỏ đến đầu địa chỉ của class.

Ví dụ :

PHP Code:

class test{ public : int val; void func[]{ cout func[]; return 0; }

Con trỏ struct :

Tương tự class,không khác lắm

Code:

struct test{

int val;

};

int main[int argc, char* argv[]]

{

test t;

t.val =2;

test *p = &t;

cout val;

return 0;

}

Các phép toán trên con trỏ :

PHP Code:

`int *p;`0

`int *p;`1

`int *p;`2

`int *p;`3

`int *p;`4

Mảng và con trỏ.

Nếu ta khai báo :

Code:

`int *p;`5

foo[0]=2;

foo[1]=3;

int *f = foo;

printf[“%d \n%d”,*[f++],*f];

Kết quả

2

3

Vậy là con trỏ f trỏ đến vị trí đầu tiên của mảng[foo[0]]

Như vậy,nếu muốn xuất 1 mảng,chỉ cần viết :

Code:

`int *p;`6

printf[“%d”,*[f+i]];

}

//——————–

Lấy byte thứ i trong 1 biến n byte :

Code:

`int *p;`7

char *p = [ char * ] &a;

int i = 3;

printf[“%p”,p[i]];

Kiểm tra hệ thống là little endian hay big endian

Code:

`int *p;`8

if[*[char *]&num] = 78]{

printf[“Little Endian”];

}

else printf[“Big Endian”];

con trỏ hằng là 1 optional ability trong lập trình, tác dụng của nó tựa như là phương thức hằng trong C++;

ý nghĩa là 1 con trỏ, trỏ đến 1 ô nhớ, nhưng ko được quyền thay đổi giá trị của ô nhớ đó

Code:

`int *p;`9

const int *p;

p=&a;

Chủ Đề