Quản lý bộ nhớ trong eVC-HELPppppppp

Tư Triều

GẮN KẾT
GÂY DỰNG
Các bác có kinh nghiệm lcao thủ ập trình trong eVC post vài bài về quản lý bộ nhớ giúp anh em mới vào nghề cái.
Em có một vấn đề sau về bộ nhớ
Em cần một mảng CPoint diem[500][10]
Nếu em khai theo kiểu mảng động:
trong header: CPoint **diem;
trong ctrình cấp phát dần :
diem=new CPoint *; // i<500
diem[k]=new CPoint[10];
thì khi cho i tầm 30-40 thì chương trình báo lỗi .
Nếu em khai ngay từ đầu CPoint diem[500][10] thì lại không có lỗi.
Theo ý kiến chủ quan nếu cấp phát động thì tốt hơn và tiết kiệm hơn, tại sao lại lỗi hả các bác???
 

DellAximX5

androidcore.com
GẮN KẾT
GÂY DỰNG
Tư Triều said:
Nếu em khai theo kiểu mảng động:
trong header: CPoint **diem;
trong ctrình cấp phát dần :
diem=new CPoint *; // i<500
diem[k]=new CPoint[10];
thì khi cho i tầm 30-40 thì chương trình báo lỗi .
Nếu em khai ngay từ đầu CPoint diem[500][10] thì lại không có lỗi.
Theo ý kiến chủ quan nếu cấp phát động thì tốt hơn và tiết kiệm hơn, tại sao lại lỗi hả các bác???


Cấp phát dần là sao bác?
Nếu muốn dùng mạng động kích thước [500][10] thì mình có thể làm như sau:

Mã:
int n = 500, m = 10;
	CPoint **diem;
	diem = new CPoint*[n];
	int i, j;
	for (i=0; i<n; i++){
		diem[i] = new CPoint[m];
	}

	
	for (i=0; i<n; i++){
		for (j=0; j<m; j++){
			CPoint p;
			p.x = i;
			p.y = j;
			diem [i][j] = p;
			CString s;
			s.Format(TEXT("%d, %d"), diem[i][j].x, diem[i][j].y);
			this->SetWindowText(s);
		}
	}

	for (i=0; i<n; i++){
		delete diem[i];
	}

	delete diem;

Bạn nhớ giải phóng bộ nhớ sau khi dùng! Quên giải phóng bộ nhớ là 1 lỗi cơ bản mà nhiều người mắc phải.
 

Tư Triều

GẮN KẾT
GÂY DỰNG
:) May quá có người quan tâm giúp rồi.

Xóa bộ nhớ sao lại phải xóa 2 lần như thế ạ, em tưởng delete diem là đựoc chứ ạ, cần cả vòng lặp để xóa như thế kia nữa hả bác??

Cấp phát dần có nghĩa là biến n, và trong a[n][m] trong từng trường hợp là khác nhau ( nhưng đều <500). Em mới nghĩ cấp phát dần là cách làm để tiết kiệm bộ nhớ nhất.
Bác cho em hỏi, cách của bác với cách khai thẳng
int ARR[500][10] là không khác nhau đúng không ?

khai báo ngay từ đầu int ARR[500][10] trong eVC là nó cấp phát bộ nhớ luôn đúng không ạ ?

Sao trong một số trường hợp khai báo như kiểu của bác, dùng xong delete đi thì lỗi thiếu bộ nhớ, trong khi khai báo ngay từ đầu kiểu int ARR[500][10] lại không lỗi bộ nhớ?

Có cách nào để biết được các thông số về bộ nhớ, quản lý bộ nhớ của chương trình mình làm không các bác
Xin chân thành cảm ơn .
 

DellAximX5

androidcore.com
GẮN KẾT
GÂY DỰNG
Hì vấn đề bộ nhớ có khá nhiều cái hay, mình rất khoái các vấn đề liên quan đến hệ thống, nhưng do chưa thể dùng nó để kiếm sống được nên đã quẳng vào kho hơi lâu. Hôm nay có bác Tư Triều vào lục lại giùm thì cảm ơn nhiều quá. Những điều mình nói ở đây mang tính chất bàn luận, bác nào thấy sai thì sửa giúp.

Tư Triều said:
:) May quá có người quan tâm giúp rồi.

Xóa bộ nhớ sao lại phải xóa 2 lần như thế ạ, em tưởng delete diem là đựoc chứ ạ, cần cả vòng lặp để xóa như thế kia nữa hả bác??

hix, tèo rồi, cấp phát phải dùng vòng for thì xoá cũng phải dùng vòng for chứ ;)

Nếu bạn khai báo **diem nghĩa là sao? Bạn hình dung được ko?
- Nếu ban khai báo CPoint diem[n][m] có nghĩa là bạn đã cấp phát tính 1 khối bộ nhớ mà mình thường gọi là 1 ma trận có kích thước n x m. Nhưng thực tế không phải vậy, thực tế thì khối bộ nhớ này là liên tiếp nhau, mình hoàn toàn có thể dùng 1 vòng for để tra cứu, thay đổi vùng nhớ này (không cần dùng 2 vòng for như ta vẫn thường dùng).
- Còn nếu bạn khai báo CPoint **diem tức là mình muốn có 1 khối nhớ chưa biết trước kích thước. Khi nào mình cần dùng bao nhiêu thì sẽ xin bấy nhiêu. Tại sao phải làm vậy, mục đích chính chẳng qua là để tận dụng không gian nhớ. Chắc bạn đã nghe tới chuyện phân mảnh bộ nhớ chứ? Tại sao, nếu bạn đã học về Hệ điều hành thì chắc biết rằng sẽ có trường hợp là bộ nhớ còn dư rất nhiều nhưng khi mình xin cấp phát 1 miếng thì OS lại báo là "hết bộ nhớ rồi bác à", đó là trường hợp phân mảnh bộ nhớ. Vấn đề này mình tạm dừng ở đây vì nói ra sẽ rất dài dòng, đụng tới quản lý tài nguyên của OS mà, nếu bạn có nhã hứng thì mình chờ ý kiến của bạn để tiếp tục câu chuyện. Quay lại vấn đề chính: bạn đã bao giờ có nhu cầu cần 1 mảng mà mảng đó có dạng m x nj ko? Có nghĩa là mình cần 1 mảng mà có m hàng, mỗi hàng bây giờ không còn là n cột nữa, mà hàng 1 có 4 cột, hàng 2 có 10 cột, hàng 3 có 6 cột, ... hì, tạm dừng vấn đề nhé. Tiếp tục quay lại vấn đề, bạn hỏi là tại sao phải cùng vòng for để xoá: thế bạn khai báo CPoint **diem nghĩa là sao? Nghĩa là con trỏ của con trỏ, đúng ko? Mà con trỏ thì phải dùng delete, thế con trỏ của con trỏ thì phải dùng 2 lần delete chứ sao. Tóm lại bạn có thể hình dung là mảng các con trỏ thì phải dùng vòng for để del, đúng ko?

Tư Triều said:
Cấp phát dần có nghĩa là biến n, và trong a[n][m] trong từng trường hợp là khác nhau ( nhưng đều <500). Em mới nghĩ cấp phát dần là cách làm để tiết kiệm bộ nhớ nhất.

Như vậy, mỗi lần cấp phát lại bạn phải del cái cũ đi rồi cấp phát cái mới hoặc bản phải dùng các hàm hỗ trợ.

Tư Triều said:
Bác cho em hỏi, cách của bác với cách khai thẳng
int ARR[500][10] là không khác nhau đúng không ?

Sao bạn lại hỏi thế này nhỉ? Bạn đọc phần trả lời trên cùng của mình chắc sẽ hình dung ra. Câu trả lời là khác rất xa nhau. Đặc biệt sẽ thể hiện rõ khi bạn cần 1 mảng kích thích lớn, chẳng hạn: 9999999 x 9999999. Ai mà cũng khai báo dạng CPoint diem[9999999][9999999] thì chắc là sẽ khổ bác Bill lắm đây.

Tư Triều said:
khai báo ngay từ đầu int ARR[500][10] trong eVC là nó cấp phát bộ nhớ luôn đúng không ạ ?

Đúng. (Nhưng đừng ạ, mình ngại lắm, mình còn ít tuổi lắm :) )

Tư Triều said:
Sao trong một số trường hợp khai báo như kiểu của bác, dùng xong delete đi thì lỗi thiếu bộ nhớ, trong khi khai báo ngay từ đầu kiểu int ARR[500][10] lại không lỗi bộ nhớ?

Hì bởi vì bạn dùng chưa đúng, bạn del có 1 lần thôi chứ gì?

Tư Triều said:
Có cách nào để biết được các thông số về bộ nhớ, quản lý bộ nhớ của chương trình mình làm không các bác

VC ở chế độ debug thông báo rất rõ, hoặc mình có thể làm các test case.

Tư Triều said:
Xin chân thành cảm ơn .
Không có chi, khách sáo quá, trao đổi học hỏi kinh nghiệm là chính thôi mà :)
 

Tư Triều

GẮN KẾT
GÂY DỰNG
Okie, đêm qua em đã khắc phục được rồi.
More Q :
- Về nguyên tắc đâu đó trong PC thì bộ nhớ sử dụng có thể lên được 4G
nhưng trong PDA bác có biết maxxi là ??
- Nếu khai báo kiểu int *a rồi sau đó dùng luôn a[1]=10 chẳng hạn thì trong một số trường hợp không lỗi, bác có thể phân tích cụ thể hơn chuyện này không.Cụ thể ở mức hệ điều hành làm gì thì tốt.

Xin chân thành cảm ơn.
Nhỏ lớn khôgn quan trọng, biết hơn thì vẫn truyền thụ được như thường.
 

DellAximX5

androidcore.com
GẮN KẾT
GÂY DỰNG
Tư Triều said:
Okie, đêm qua em đã khắc phục được rồi.
More Q :
- Về nguyên tắc đâu đó trong PC thì bộ nhớ sử dụng có thể lên được 4G
nhưng trong PDA bác có biết maxxi là ??
dwProcessorType
The following list shows the possible values for this member:

PROCESSOR_INTEL_386
PROCESSOR_INTEL_486
PROCESSOR_INTEL_PENTIUM
PROCESSOR_INTEL_PENTIUMII
PROCESSOR_MIPS_R4000
PROCESSOR_HITACHI_SH3
PROCESSOR_HITACHI_SH4
PROCESSOR_STRONGARM
PROCESSOR_ARM720
PROCESSOR_MIPS_R5000
PROCESSOR_SHx_SH3DSP

Nhìn những dòng trên bạn thấy WM hỗ trợ cả CPU intel 386, tức là có tới 32 bit địa chỉ, cũng có nghĩa là - về mặt lý thuyết - nó sẽ hỗ trợ được tối đa 4GB mem như Windows trên PC.

Tư Triều said:
- Nếu khai báo kiểu int *a rồi sau đó dùng luôn a[1]=10 chẳng hạn thì trong một số trường hợp không lỗi, bác có thể phân tích cụ thể hơn chuyện này không.Cụ thể ở mức hệ điều hành làm gì thì tốt.

Hì dùng thế này có lúc được lúc không có nghĩa là, lúc được là do chẳng may, còn lúc không được mới là đúng.

Khi bạn khai int *a thì bạn đã được 1 con trỏ, trỏ đến 1 vùng nhớ bất kỳ không được xác định. Do đó khi bạn gán a[1] = 10, thì ô nhớ đầu tiên được gán bằng 10. Không gây ra lỗi đó là do đoạn mã khác chưa dùng tới ô nhớ đó. Bạn chạy chương trình 1 lúc thế nào cũng sinh lỗi ;) Bạn phải cấp phát bộ nhớ thì ô nhớ mình dùng tới sẽ được đánh dấu là "đang dùng", khi đó đoạn mã khác mới ko xâm phạm vào và ko sinh lỗi.
 

Bài viết cần bạn xem thêm

Gửi All
Theo mình để đảm bảo tính minh bạch cũng như an toàn trong việc tham gia đấu giá nên chăng hhvn nên xác thực tài khoản tất cả các thành viên tham gia đấu giá. Xác thực tài khoản bằng việc yêu cầu thanh viên tham gia phải xác thực giấy tờ tuỳ ...
Top