01/10/2018, 08:20
Khi realloc cho con trỏ cấp 2 thì có nhất thiết phải dùng vòng lặp duyệt lại từ đầu để cấp phát cho từng con trỏ cấp 1 của nó không?
Giả sử e có 1 đoạn code cấp phát cho level 2-pointer như sau:
int **arr = (int **)calloc(3, sizeof(int *));
for (int i = 0; i < 3; ++i) {
arr[i] = (int *)calloc(5, sizeof(int));
}
...
thì khi em realloc lại cho con trỏ arr
với kích thước lớn hơn thì có nhất thiết phải dùng vòng lặp duyệt lại từ đầu để cấp phát cho mỗi con trỏ cấp 1 trong nó không ạ ? Hay chỉ cấp phát cho con trỏ ở cuối thôi ?
realloc(arr, 4 * sizeof(int *));
for (int i = 0; i < 4; ++i) {
arr[i] = (int *)calloc(5, sizeof(int));
}
...
hay
realloc(arr, 4 * sizeof(int *));
arr[3] = (int *)calloc(5, sizeof(int));
?
Còn nếu realloc con trỏ arr
với kích thước bé hơn thì dữ liệu trong matrix sẽ bị mất đi đúng ko ạ ?
Cảm ơn mọi người nhiều
Bài liên quan
Không, nó bảo toàn nội dung vùng nhớ luôn. http://en.cppreference.com/w/c/memory/realloc
Tất nhiên thu hẹp vùng nhớ thì sẽ mất 1 số slot nên bạn phải
free
trước các con trỏ cấp 1 phía sau.À anh @rogp10 ơi, sẵn tiện cho e hỏi luôn là:
nếu
realloc
con trỏ cấp 2arr
như sau:arr = (int **)realloc(arr, 69 * sizeof(...));
thì nó bị lỗi runtime
còn để:
realloc(arr, 69 * sizeof(...));
thì nó không bị lỗi.Anh có thể giải thích cho e ko ?
em tưởng khi realloc lesser lại thì mấy con trỏ cấp 1 phía sau nó tự động giải phóng luôn ?
Raw pointer của C/C++ không có auto GC
Tức là nó ko tự giải phóng khi mình realloc ạ ?
Vậy khi em realloc lesser thì mấy con trỏ cấp 1 ở sau cùng nó bị mất ra khỏi mảng thôi chứ vẫn còn trong bộ nhớ ạ ?
Sẵn tiện anh @rogp10 cho em hỏi đoạn code sau dùng để thêm dòng vào ma trận đã đúng chưa ạ:
Em run thử thấy cũng ok nhưng về mặt cú pháp, cấu trúc, … đồ ko biết có sai ko ?
Những vùng nhớ đó vẫn chưa được
free
và về nguyên tắc là sau khi thu gọn thì ko dùng được mấy slot đó nữa nên cũng khôngfree
được.Đây là 1 điều khá kỳ quặc của C nếu hàm không có prototype đầy đủ thì coi như nó trả về
int
. Oái oăm là chỉ khi cast trực tiếp mới bị dính đòn.Thực ra con trỏ void* đổi trực tiếp qua int* (và bất cứ kiểu con trỏ gì) là hợp lệ (nhưng giữa hai kiểu không void thì sẽ bị lỗi). Vì vậy không cần phải cast với {m|re|c}alloc. Và để cho chính xác thì nên viết ntn:
arr = realloc(arr, sizeof(*arr) * n);
Ko hiểu gì hết anh ơi
Em thấy lâu lâu để
arr = (int **)realloc(arr, (rows + 1) * sizeof(int* ))
;thì ko có lỗi, tự dưng trong code trên thì lại bị lỗi, phải để:
realloc(arr, (rows + 1) * sizeof(int* ));
Edit: À, nó bị lỗi không phải do
arr = (int **)realloc(...)
mà do chỗ khác Nhưng em vẫn chưa hiểu lắm câu giải thích của anh @rogp10ANSI C(C89) cho bạn xài hàm mà ko có prototype (trường hợp này nó nằm ở
stdlib.h
), chỉ cần tới khi build mà mình có là dùng được thôi. Lúc này (khi chưa build) thì compiler vẫn cho rằngrealloc
trả về int. Vấn đề là realloc trả về con trỏ nên dính undefined => BOOM. Có người cast mới bị lỗi, không cast không lỗi rất là mindscrew (mấy cái undefined này nó vậy). Nên đúng nhất là dùng mấy hàm này phải#include <stdlib.h>