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 ạ!
ơ 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
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ử ạ ??
thì mỗi lần nhập thêm realloc mảng lại
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.
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 ?
Bạn phải phân biệt được
run time
vàcompile time
.compile time
là mọi thứ đã được sắp đặt trước. Ví dụ như bạn khai báoNhư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ùngcompile time
. Và do đó bạn cần vớimalloc
.Còn nhiều thứ khác mà
malloc
giải quyết được vấn đề lắm.độ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
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.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 đỡ ạ
Hi Thân Hoàng.
Khúc mắc của bạn là gì ?
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
Hàm realloc() resize mảng, nhưng sau khi realloc thì dữ liệu cũ có còn không ạ .?
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ùngmalloc
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ạiNế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 .?
Cần bao
n
thì xinn
. Dùng xong trả lại đừng đùng đến.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
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)
Đúng với tính chất website anh nhỉ :)) dạy nhau học
Chắc từ bây giờ em bỏ fb sang hoạt động dnh quá :)) học hỏi được bao thứ hay ho
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.