01/10/2018, 10:35

Mảng động - Static Array

Chào mọi người, em có một vấn đề về mảng động vẫn mông lung nên hôm nay đăng bài nhờ mọi người thông não ạ

Theo em được biết thì: Mảng động (Static Array) được dùng khi muốn tối ưu chương trình khi không biết trước số phần tử của mảng, vì nó sử dụng vừa đủ lượng tài nguyên nó cần, và giải phóng bộ nhớ khi dùng xong. Hàm Malloc(hay alloc()) đảm nhiệm việc này.
Tuy nhiên: khi cấp phát động thì cú pháp của nó lại là: (int*)malloc(số phần tử*kích thước của một phần tử)
Điều này lại hơi sai sai, vì nếu cần chạy một chương trình mà trong đó có một mảng không biết trước số phần tử thì việc sử dụng malloc lại gặp vấn đề. Vì theo cú pháp của nó thì phải biết số phần tử và kích thước của phần tử thì mới cung cấp cho nó số ô nhớ được chứ ?

Mong mọi người giúp đỡ, em xin cảm ơn ạ!

chichi viết 12:38 ngày 01/10/2018

ơ hay lúc bạn cần cấp phát động thì bạn phải biết số phần tử của mảng rồi chứ ?, ví dụ chương trình hỏi nhập bao nhiêu sinh viên người dùng nhập 10 thì cấp phát mảng chứa 10 sinh viên thay vì mảng tĩnh từ đầu không biết số lượng sinh viên. Lúc sau muốn thêm thì dùng realloc

Thân Hoàng viết 12:46 ngày 01/10/2018

Ví dụ là nhập mảng n phần tử đến khi nhập 0 thì ngưng. Như vậy thì làm sao biết trước được số phần tử ạ ??

chichi viết 12:45 ngày 01/10/2018

thì mỗi lần nhập thêm realloc mảng lại

Tao Không Ngu. viết 12:46 ngày 01/10/2018

Hi Thân Hoàng.
Tìm sách về cấu trúc dữ liệu giải thuật để đọc. Trong đó có giải pháp.

Thân Hoàng viết 12:40 ngày 01/10/2018

vâng.
Vậy thì cái tính chất “động” của Static array nó nằm ở free() và realloc() phải không anh ?

Henry viết 12:37 ngày 01/10/2018

Bạn phải phân biệt được run timecompile time.
compile time là mọi thứ đã được sắp đặt trước. Ví dụ như bạn khai báo

int class[20];   // xin 80 bytes cho 20 phần tử mảng arr (20 * 4)

Nhưng nếu bỗng nhiên bạn lại có một lớp học hơn hai chục thằng thì làm sao? Bạn sẽ nghĩ đến việc ta sẽ có độ dài một mảng bằng cách nhập input. Và đương nhiên input này sẽ được nhập trong quá trình chạy run time và nó không hề được dự đoán trước vì biết bạn nhập cái gì thế nên không thể dùng compile time. Và do đó bạn cần với malloc.
Còn nhiều thứ khác mà malloc giải quyết được vấn đề lắm.

chichi viết 12:43 ngày 01/10/2018

động ở chỗ là bạn biết cần xin cấp bao nhiêu, xin cấp lại được với lúc nào không cần nữa thì trả lại

rogp10 viết 12:41 ngày 01/10/2018

Thực ra có thể dùng mảng tự co giãn (như std::vector) vậy, nhưng trong C phải dùng thư viện ngoài. Và vấn đề đặt ra là 1 số ô mem sẽ bị thừa, nhưng vấn đề là OS cũng để thừa ra như vậy, nên trừ phi bạn biết rõ kernel làm gì với mem thì khó nói lắm.

Thân Hoàng viết 12:43 ngày 01/10/2018

Em hiểu rồi.
Để giải quyết cái khúc mắc của em thì chỉ cần dùng realloc() là được.
Cảm ơn mọi người giúp đỡ ạ

Tao Không Ngu. viết 12:49 ngày 01/10/2018

Hi Thân Hoàng.
Khúc mắc của bạn là gì ?

rogp10 viết 12:49 ngày 01/10/2018

ơ hay lúc bạn cần cấp phát động thì bạn phải biết số phần tử của mảng rồi chứ ?, ví dụ chương trình hỏi nhập bao nhiêu sinh viên người dùng nhập 10 thì cấp phát mảng chứa 10 sinh viên thay vì mảng tĩnh từ đầu không biết số lượng sinh viên.

Mình xài bao nhiêu soft rồi không có soft nào hỏi trước bao nhiêu cả

Với realloc thì quyết định nằm ở OS, còn C++ đã có std::vector

Thân Hoàng viết 12:52 ngày 01/10/2018

Hàm realloc() resize mảng, nhưng sau khi realloc thì dữ liệu cũ có còn không ạ .?

Henry viết 12:44 ngày 01/10/2018

Còn
Hãy tưởng tượng như thế này. Cái bộ nhớ mà bạn dùng malloc để lấy là heap và bạn coi đó là một cái nhà kho đi. Khi bạn dùng malloc nó sẽ đưa cho bạn cái địa chỉ mà chưa ai sử dụng, thế là bạn dùng ở đó, để đồ ở đó, sau khi chán bạn nói với nó tao không dùng nữa. Thế là chỗ đấy thành một chỗ được coi là chưa ai dùng và vẫn còn đồ của bạn ở đó. Tuy nhiên cái nhà kho này luật lệ không nghiêm khắc, bạn vẫn có thể thò tay vào để lấy đồ dùng, rồi vứt ở đó bình thường (lấy dữ liệu và thay đổi). Tuy nhiên chỗ đó là nơi không ai quản lí, và dĩ nhiên là nó có thể được cấp phát cho một chương trình khác. Thế nên có khả năng sẽ có lỗi diễn ra. Do đó hãy tuân thủ một theo lí thuyết xin -> trả và đừng dùng lại

Thân Hoàng viết 12:51 ngày 01/10/2018

Nếu em sử dụng malloc và realloc như bác bên trên hd thì có bị lỗi gì không anh .?

Henry viết 12:51 ngày 01/10/2018

Cần bao n thì xin n. Dùng xong trả lại đừng đùng đến.

Thân Hoàng viết 12:43 ngày 01/10/2018

Những kiến thức mà anh nói đến, do anh học khi học C hay học môn nào vậy ạ ??
Bởi vì em thấy các sách về lập trình chỉ nói về cú pháp và ví dụ chứ không đi sâu vào cách mà hệ thống hoạt động ntn

Henry viết 12:52 ngày 01/10/2018

Biết tới phần này, có thắc mắc y chang như vậy. Cái thử xin rồi trả sau đó dùng thì vẫn ngon. Đi search trên stack thì họ nói cái ví dụ đó (mình mới translate)

Thân Hoàng viết 12:44 ngày 01/10/2018

Đúng với tính chất website anh nhỉ :)) dạy nhau học

Thân Hoàng viết 12:44 ngày 01/10/2018

Chắc từ bây giờ em bỏ fb sang hoạt động dnh quá :)) học hỏi được bao thứ hay ho

Tao Không Ngu. viết 12:51 ngày 01/10/2018

HI Thân Hoàng.
realloc() phần dữ liệu cũ bảo toàn. Tuy nhiên nó làm phân mảnh bộ nhớ dẫn đến các hậu quả xấu.
Thường thì dùng danh sách liên kết cho các trường hợp cần cấp phát nhiều liên tục hoặc chiến lược cấp phát lại theo kiểu vector cấp phát gấp đôi. (bạn có thể xem một bài đánh giá của anh Dạt về các kiểu dữ liệu lưu trữ trong C++).

P/S Nếu bạn là người mới thì nên bắt đầu với các kiến thức cơ bản như debug và C cơ bản sau đó là cấu trúc dữ liệu và giaỉ thuật khi đó bớt được nhiều câu hỏi.

Bài liên quan
0