Jump to content


Hình ảnh

Mảng 2 chiều trong C++


  • Please log in to reply
41 replies to this topic

#1 kao_buk

kao_buk

    ....fixbugging myself !!!

  • Thành viên
  • PipPipPipPipPip
  • 489 bài viết
  • Giới tính:Nam
  • Nơi sống:Xứ Nghệ
  • Sở thích:Chưa nghĩ ra !

Gửi lúc 25 Oct 2008 - 12:21 PM

Mình có test 1 đoạn code bằng C++ về mảng 2 chiều, thì bắt gặp lỗi khi run.

#include<iostream>
using namespace std;
int main()
{
	int arr[1000][1000];
	for(int i=0;i<1000;i++)
	for(int j=0;j<1000;j++)
	{
		cout<<"done!"<<endl;
	}
	return 0;
}

Nhưng, nếu giảm cỡ của mảng xuống thì chạy bình thường:

#include<iostream>
using namespace std;
int main()
{
	int arr[100][100];		   //cỡ ở đây giảm xuống còn 10000 phần tử
	for(int i=0;i<100;i++)
	for(int j=0;j<100;j++)
	{
		cout<<"done!"<<endl;
	}
	return 0;
}

Hoặc, khai báo bằng cấp phát động, lỗi trên cũng đuợc khắc phục:

#include<iostream>
using namespace std;
int main()
{
	int(*arr)[1000]=new int[1000][1000];  //ở đây vẫn cấp phát mảng với cỡ cũ
	for(int i=0;i<1000;i++)
	for(int j=0;j<1000;j++)
	{
		cout<<"done!"<<endl;
	}
	return 0;
}

Mời các bạn đưa ra ý kiến về lỗi này? ;;)
  • 0

#2 deptrainhat_k51

deptrainhat_k51

    DiE 4 r0cK!

  • Member of FOTECH Assembly
  • PipPipPipPipPip
  • 2128 bài viết
  • Giới tính:Nam
  • Nơi sống:Người Hà Tĩnh

Gửi lúc 25 Oct 2008 - 12:41 PM

Lý do là khi khai báo mảng int arr[1000][1000] thì chương trình sẽ yêu cầu được cấp phát một vùng nhớ liên tiếp trên bộ nhớ, có kích thước khá lớn: 1000x1000x2 = 2000000 (bytes), HĐH không tìm thấy vùng nào lớn như vậy trên bộ nhớ nên báo lỗi. Còn cấp phát động thì nó sẽ không lấy 1000X1000 ô nhớ liên tiếp nữa, mà sẽ lấy từ 1000 nơi khác nhau 1000 ô liên tiếp, nên chạy thoải mái :)
  • 0

#3 kao_buk

kao_buk

    ....fixbugging myself !!!

  • Thành viên
  • PipPipPipPipPip
  • 489 bài viết
  • Giới tính:Nam
  • Nơi sống:Xứ Nghệ
  • Sở thích:Chưa nghĩ ra !

Gửi lúc 25 Oct 2008 - 01:01 PM

Lý do là khi khai báo mảng int arr[1000][1000] thì chương trình sẽ yêu cầu được cấp phát một vùng nhớ liên tiếp trên bộ nhớ, có kích thước khá lớn: 1000x1000x2 = 2000000 (bytes), HĐH không tìm thấy vùng nào lớn như vậy trên bộ nhớ nên báo lỗi. Còn cấp phát động thì nó sẽ không lấy 1000X1000 ô nhớ liên tiếp nữa, mà sẽ lấy từ 1000 nơi khác nhau 1000 ô liên tiếp, nên chạy thoải mái :)


với Ram 1GB = 2^30 bytes = 1 073 741 824 >> 2000 000. Liệu có thể xảy ra chuyện "không tìm thấy vùng nhớ" ấy không? :rolleyes:
  • 0

#4 ke_da_tinh

ke_da_tinh

    Dân FOTECH

  • Thành viên
  • PipPipPipPipPip
  • 480 bài viết
  • Giới tính:Nam
  • Nơi sống:K52

Gửi lúc 25 Oct 2008 - 01:04 PM

Nghe anh đẹp zai trả lời có vẻ có lý nhưng mà đúng là không chính xác :D
Theo em là: khi cấp phát a[1000][1000] thì nó sẽ được cấp phát trong vùng nhớ tĩnh(static) mà vùng nhớ này có giới hạn còn khi cấp phát động theo kiểu anh kao buk ( thực ra vẫn chưa "động" lắm) thì nó sẽ được cấp phát trong vùng heap, hình như độ lớn vùng này phụ thuộc nhiều vào Ram của chúng ta có bao nhiêu, thế thôi :D
  • 0
Đừng hỏi vì sao anh yêu em, anh sẽ không trả lời....thật


#5 merrymenvn

merrymenvn

    Lấy của người giàu, chia cho người nghèo

  • Thành viên
  • PipPipPipPipPip
  • 748 bài viết
  • Giới tính:Nam

Gửi lúc 25 Oct 2008 - 01:07 PM

Lý do là khi khai báo mảng int arr[1000][1000] thì chương trình sẽ yêu cầu được cấp phát một vùng nhớ liên tiếp trên bộ nhớ, có kích thước khá lớn: 1000x1000x2 = 2000000 (bytes), HĐH không tìm thấy vùng nào lớn như vậy trên bộ nhớ nên báo lỗi. Còn cấp phát động thì nó sẽ không lấy 1000X1000 ô nhớ liên tiếp nữa, mà sẽ lấy từ 1000 nơi khác nhau 1000 ô liên tiếp, nên chạy thoải mái :)


Giải thích chưa chính xác.
Thực hành tin tuần trước, em cũng làm bài tương tự. Không nhớ là khai báo như trên hay cấp phát động nhưng nếu để 99999 thì chạy được, cứ cho lên 1000000 là lỗi. Chẳng nhẽ lần nào cũng thiếu chỗ cho 1 int hay sao? Em nghĩ lỗi là do giới hạn 1000000, cụ thể là gì thì không biết. :D
  • 0

#6 ke_da_tinh

ke_da_tinh

    Dân FOTECH

  • Thành viên
  • PipPipPipPipPip
  • 480 bài viết
  • Giới tính:Nam
  • Nơi sống:K52

Gửi lúc 25 Oct 2008 - 01:09 PM

Lý do là khi khai báo mảng int arr[1000][1000] thì chương trình sẽ yêu cầu được cấp phát một vùng nhớ liên tiếp trên bộ nhớ, có kích thước khá lớn: 1000x1000x2 = 2000000 (bytes), HĐH không tìm thấy vùng nào lớn như vậy trên bộ nhớ nên báo lỗi. Còn cấp phát động thì nó sẽ không lấy 1000X1000 ô nhớ liên tiếp nữa, mà sẽ lấy từ 1000 nơi khác nhau 1000 ô liên tiếp, nên chạy thoải mái :)


Thêm phát nữa, chạy thử đoạn code này sẽ biết là các các phần tử trong mảng có "liền" nhau hay không (bây giờ hầu như int là 4 byte = kiểu long hết chứ không phải 2 byte nữa )
#includeusing namespace std;int main(){    int(*a)[1000]=new int[1000][1000];  //o+? ?ây va^~n ca^'p phát ma?ng vo+'i co+~ cu~    int dem =0;    for(int i=0;i<1000;i++)    for(int j=0;j<1000;j++)    {        a[i][j] = 1;        cout << int(&(a[i][j])) << endl;    }    cin.get();    return 0;}

Bài viết này được chỉnh sửa bởi ke_da_tinh: 25 Oct 2008 - 01:10 PM

  • 0
Đừng hỏi vì sao anh yêu em, anh sẽ không trả lời....thật


#7 CasperPas

CasperPas

    Maintains the harmony of the universe

  • Admin
  • PipPipPipPipPip
  • 2625 bài viết
  • Giới tính:Nam
  • Nơi sống:where the heart is

Gửi lúc 25 Oct 2008 - 01:22 PM

Cas thử phát nhé. nếu chương trình chạy trên console (command line), thường thì nó sẽ sử dụng chế độ gọi là Real Mode (16bit). Mảng cấp phát tĩnh sẽ xin cấp phát bộ nhớ thành 1 dải liền nhau trong memory, với số byte là tổng số phần tử của mảng. Nó dùng Segment và Offset để địa chỉ các phần tử của mảng. Mà địa chỉ này trong chế độ 16bit thì chỉ đánh địa chỉ (offset) được tối đa là 65536 bytes (64K). cấp phát tĩnh không làm được điều này. Nhưng với việc cấp phát động bằng con trỏ, ta sẽ tạo ra được 1000 cái mảng 1 chiều nằm rải rác trong bộ nhớ, mỗi mảng chỉ gồm 1000 phần tử kiểu int (4bytes) -> 4000bytes -> không vấn đề gì xảy ra cả.

Đại khái thế, chả biết đúng không. anh em góp ý cho Cas phát :lol:
  • 0

I'm not different. I'm Unique.


#8 merrymenvn

merrymenvn

    Lấy của người giàu, chia cho người nghèo

  • Thành viên
  • PipPipPipPipPip
  • 748 bài viết
  • Giới tính:Nam

Gửi lúc 25 Oct 2008 - 01:39 PM

Cas thử phát nhé. nếu chương trình chạy trên console (command line), thường thì nó sẽ sử dụng chế độ gọi là Real Mode (16bit). Mảng cấp phát tĩnh sẽ xin cấp phát bộ nhớ thành 1 dải liền nhau trong memory, với số byte là tổng số phần tử của mảng. Nó dùng Segment và Offset để địa chỉ các phần tử của mảng. Mà địa chỉ này trong chế độ 16bit thì chỉ đánh địa chỉ (offset) được tối đa là 65536 bytes (64K). cấp phát tĩnh không làm được điều này. Nhưng với việc cấp phát động bằng con trỏ, ta sẽ tạo ra được 1000 cái mảng 1 chiều nằm rải rác trong bộ nhớ, mỗi mảng chỉ gồm 1000 phần tử kiểu int (4bytes) -> 4000bytes -> không vấn đề gì xảy ra cả.

Đại khái thế, chả biết đúng không. anh em góp ý cho Cas phát :lol:


#include<iostream>
using namespace std;
int main()
{
	int arr[1000][500];
	for(int i=0;i<1000;i++)
	for(int j=0;j<1000;j++)
	{
		cout<<"done!"<<endl;
	}
	return 0;
}

Nếu như anh nói thì giới hạn là 64k, đoạn code trên dùng 1000k vẫn bình thường.
  • 0

#9 Tuandigital

Tuandigital

    Bravo Bravo!!!

  • Thành viên
  • PipPipPipPip
  • 328 bài viết
  • Giới tính:Nam
  • Nơi sống:Hoài Đức, HN
  • Sở thích:Dancing, Dance music, Internet, Đọc báo

Gửi lúc 25 Oct 2008 - 02:04 PM

Thế này thì sao nhỉ ? Vẫn Run bthg! :huh:
#include<iostream>
using namespace std;
int			 arr[1000][1000];

int main()
{
	for(int i=0;i<1000;i++)
	for(int j=0;j<1000;j++)
	{
		cout<<"done!"<<endl;
	}
	return 0;
}

  • 0

#10 Kai

Kai

    Quyết thành chính quả

  • Moderators
  • PipPipPipPipPip
  • 1328 bài viết
  • Giới tính:Nam
  • Nơi sống:Underground

Gửi lúc 25 Oct 2008 - 02:05 PM

Tống cái khai báo mảng ra toàn cục xem nào :D.

Cái này là do việc locate vùng nhớ của compiler mà thôi. :D. Chả có bit mode miếc gì đâu. Nghe đau đầu lắm :|

Bài viết này được chỉnh sửa bởi Kai: 25 Oct 2008 - 02:07 PM

  • 0

Sống là để không chết chứ không phải để trở thành anh hùng.




0 người đang đọc chủ đề này

0 thành viên, 0 khách, 0 thành viên ẩn