01/10/2018, 08:42

Hỏi về cấp phát động trong C

em đang học về cấp phát động và có được yêu cầu tạo mảng 2 chiều.
Khi em cho chạy dòng code bên dưới thì nó không báo lỗi nhưng nó không hiển thị gì cả, cũng không cho kết thúc chương trình.

int main()
{
    char **ds;
    int m=10, i;
    ds=(char*) calloc(m, sizeof(char));
    for(i=0;i<m;i++)
        ds[i]=calloc(30,sizeof(char));
    ds=(char*) realloc(ds, m);
    free(ds);
    system("pause");
    return 0;
}

Chương trình code blocks có hiển thị mũi tên màu vàng ở realloc

Nếu em bỏ vòng lặp for đi thì lại chạy bình thường. Có ai biết vấn đề này là gì nói cho em với ạ. loay hoay từ tối đến giờ :<

Khoa NTA viết 10:57 ngày 01/10/2018

Có thể bạn đang bật chế độ debug (debuger) không chừng. Thử vào menu Debug để tắt nó đi (nếu không phải vậy thì mình không biết lỗi gì ). Code của bạn bình thường, không có lỗi (gì lớn), bạn cấp phát cho mảng 2 chiều thì cast là (char **) chứ không phải (char *) (dòng 8, 11), và nhớ cast (char *) (dòng 10).

Người bí ẩn viết 10:57 ngày 01/10/2018

char **ds;

Nếu ko cấp phát ngay lúc declare thì nên gán cho nó bằng NULL: char **ds = NULL;

ds=(char*) calloc(m, sizeof(char));

Sửa lại thành:

ds = (char **)calloc(m, sizeof(char *));
ds[i]=calloc(30,sizeof(char));

Sửa lại thành:

ds[i] = (char *)calloc(30, sizeof(char));
ds=(char*) realloc(ds, m);

Sửa lại thành:

ds = (char **)realloc(ds, <size>);

Còn logic code bạn tự xem xét.

Trịnh Tiến Mạnh viết 10:57 ngày 01/10/2018

cảm ơn bạn :> mình sửa được rồi

Trịnh Tiến Mạnh viết 10:42 ngày 01/10/2018

cho mình hỏi chút.
bạn giải thích cho mình sự khác nhau giữa

ds = (char **)calloc(m, sizeof(char *));

ds=(char*) calloc(m, sizeof(char));

khi không dùng tới hàm realloc, mình sử dụng theo cách

ds=(char*) calloc(m, sizeof(char));

thì bài của mình vẫn chạy bình thường.

Người bí ẩn viết 10:58 ngày 01/10/2018

ds là một con trỏ cấp 2, trong khi funtion prototype của hàm calloc là: void * calloc(size_t nitems, size_t size) thì phải ép kiểu của con trỏ cấp 2 cho hàm, ở đây là char **. Còn char * thì chỉ ép kiểu cho con trỏ cấp 1 mà dùng để ép cho ds thì sai rồi.
ds có thể hiểu đơn giản là 1 con trỏ cấp 2 chứa nhiều con trỏ cấp 1 ở bên trong, vậy khi cấp phát phải để size đúng cho nó: sizeof(char *) chứ sizeof(char) là sai. (vì sizeof(char *) khác sizeof(char)).

khi không dùng tới hàm realloc, mình sử dụng theo cách

vậy khi dùng hàm realloc thì sao? Một lần nữa, ds là con trỏ cấp 2 mà cast char * là hoàn toàn sai.
Và cách giải phóng con trỏ cấp 2 của bạn cũng sai luôn, à không phải, thiếu thôi.

Trịnh Tiến Mạnh viết 10:49 ngày 01/10/2018

cảm ơn bạn đã giải thích.

Bài liên quan
0