Yêu cầu mọi thông tin sao chép từ blog này phải được ghi rõ đầy đủ: Thông tin được sao chép từ "http://www.dangngochoangthanh.blogspot.com".

Cool wallpaper http://www.fancymessage.com

EMOJI KEYBOARD PRO http://emojiselector.com

THƯ VIỆN HÌNH ĐỘNG FLASH ANIMATION: http://flashanimationlibrary.blogspot.ru/

Hệ thống học trực tuyến đang được phát triển và sẽ đưa vào sử dụng vào cuối năm nay. Hãy xem qua một số demo của Học Trực Tuyến.


HỌC TRỰC TUYẾN ĐÃ CUNG CẤP PHIÊN BẢN TRUY CẬP QUA MOBILE http://dangngochoangthanh.blogspot.com/?m=1

XEM KÊNH HỌC TRỰC TUYẾN TRÊN YOUTUBE



Search on This Blog

Saturday, September 11, 2010

Toán tử new và new[]

Mục đích tạo ra biến con trỏ là không chỉ xử lý các tác vụ tính toán, mà còn có thể quản lý bộ nhớ máy tính. Để thực hiện điều này, chúng ta cần khai báo số ô nhớ cung cấp cho mỗi biến con trỏ, khi không còn cần dùng đến chúng nữa, chúng ta có thể giải phóng các ô nhớ này đi. Để thực hiện được những tác vụ này, trong C++ cung cấp cho ta hai toán tử là new và delete.

Toán tử new và new[]

Để yêu cầu bộ nhớ động, chúng ta sử dụng toán tử new, theo sau nó là kiểu dữ liệu. Nếu nó là mảng của nhiều phần tử, thì số phần tử sẽ được ấn định bên trong dấu [] ngay sau kiểu dữ liệu. Khi đó, nó sẽ trả về con trỏ trỏ vào khối ô nhớ đầu tiên.
int*num = new int;//Khai báo biến trỏ int 4 byte int*nums = new int[10];//Khai báo biến trỏ nums với 4*10 bytes
Tôi xin nhắc lại lần nữa, một kiểu dữ liệu tương ứng với một số lượng các ô nhớ được quy định sẵn. Như trong trường hợp này, trên hệ điều hành windows 32bit, biến num sẽ chiếm 4 bytes bộ nhớ bằng  giá trị. Còn biến nums thì chiếm 40 byte bộ nhớ, tương ứng với  giá trị.
Nếu bạn sử dụng hàm sizeof để kiểm tra kích thước của biến *nums trong trường hợp này, bạn sẽ nhận được 4. Sở dĩ như vậy là vì, sau khi khởi tạo 10 phần tử kiểu int, con trỏ sẽ đặt vào phần tử đầu tiên, cho nên, bạn sử dụng sizeof trong trường hợp này là sizeof của phần tử đầu tiên (tức kiểu int). Do đó, kết quả thu được là 4 bytes.
Khi khởi tạo cho biến trỏ trỏ vào biến trỏ khác (tạm gọi là biến trỏ nhiều tầng). Ta cần khởi tạo cho biến trỏ chung. Tương ứng với mỗi biến trỏ chung, sẽ có một mảng các biến trỏ khác tương ứng. Do đó, ta cần khởi tạo cho dãy biến trỏ này, nhờ vào vòng lặp for. Tương tự như vậy, chúng ta có thể khởi tạo cho biến trỏ đa tầng (có thể là hai, ba, bốn…).
int***num; int length = 10;
//khởi tạo biến trỏ chung
num = new int**[length];
//khởi tạo biến trỏ tầng 1
for (int i=0; i
num[i]=new int*[length];
//khởi tạo biến trỏ tầng 2
for (int i=0; i
for(int j=0; j
num[i][j]=new int[length];
Để truy cập đến từng ô nhớ, ta có thể truy cập theo num[i][j][k] hoặc *(*(*(num+i)+j)+k). Như vậy, bạn có thể thấy rằng, thực chất con trỏ cũng là một mảng. Nhưng điểm khác biệt cơ bản là mảng có kích thước cố định khi khai báo, con con trỏ có  kích thước thay đổi.
Bộ nhớ động được yêu cầu bởi chương trình, và hệ điều hành sẽ cung cấp cho nó từ bộ nhớ heap. Tuy nhiên, bộ nhớ máy tính cũng hữu hạn, và nó có thể bị cạn kiệt. Chính vì lẽ đó, chúng ta cần đến một kĩ thuật để kiểm tra tình trạng này của bộ nhớ. C++ (và thậm chí C) cung cấp cho ta hai phương thức chuẩn để kiểm tra: vượt qua ngoại lệ (throw bad_alloc) và không vượt qua ngoại lệ (nothrow bad_alloc).
Bằng việc sử dụng một ngoại lệ là bad_alloc, hệ thống sẽ bỏ qua khi quá trình cung ứng ô nhớ bị thất bại (theo mặc định). Ngoại lệ là một tính năng mạnh mẽ của C++, chúng ta sẽ tìm hiểu chi tiết ở những chương sau. Nếu gặp một ngoại lệ, chúng ta cần cho biết có bỏ qua để tiếp tục chạy chương trình hay không. Toán tử new cung cấp theo phương thức mặc định là vượt qua (throw bad_alloc).
bobby = new int[5]; //Nếu thất bại, ngoại lệ sẽ bị vượt qua – throw bad_alloc
Nếu không vượt qua ngoại lệ, mà cố gắng tiếp tục chạy chương trình, thì
bobby = new (nothrow) int[5]; //Không vượt qua ngoại lệ, chương trình cố gắng tiếp tục
Nếu sử dụng vượt qua ngoại lệ throw bad_alloc, trong trường hợp cung ứng ô nhớ bị thất bại, con trỏ sẽ trả về con trỏ null, và chương trình vẫn tiếp tục. Chúng ta chỉ cần kiểm tra biến trỏ bobby. Nếu nó là null thì quá trình cung cấp bộ nhớ động thất bại và ngược lại thì thành công. Đây là cách làm thủ công, chúng ta có thể sử dụng cấu trúc try… catch để xử lý tình huống này. Chi tiết, chúng ta sẽ thảo luận kĩ hơn trong phần sau. Lưu ý rằng, hai ngoại lệ này nằm trong thư viện new .

No comments:

Post a Comment