Làm cách nào để giải phóng toàn bộ mảng có các phần tử đã được cấp phát bộ nhớ riêng lẻ thông qua các lệnh gọi tới malloc / calloc [trùng lặp]

Aug 16 2020

Theo những gì tôi biết, malloc và calloc chỉ là các API lưu giữ sách trên bộ nhớ cơ bản. Lưu ý điều này, tôi tự hỏi liệu một lệnh gọi tới free () có giải phóng toàn bộ mảng có các phần tử riêng lẻ đã được cấp phát bộ nhớ thông qua các lệnh gọi độc lập tới malloc (hoặc calloc) hay không.

Chính xác, tôi có mã sau:

int *num,* num_start;

num_start=num;

for(i=0;i<N;i++)
{
    num = (int *)calloc(0, sizeof(int));
    num++;
}

free(num_start);

free(num_start)giải phóng toàn bộ mảng gồm N phần tử nguyên đã được cấp phát động không gian độc lập không?

Trả lời

1 P__JsupportswomeninPoland Aug 16 2020 at 10:09

"Mã" bạn đã đăng không có ý nghĩa gì và sai.

int *num, num_start;
num_start=num;

num_start là một số nguyên không phải là con trỏ.

for(i=0;i<N;i++)
{
    num = (int *)calloc(0, sizeof(int));
    num++;
}

thành thật mà nói, tôi không hiểu mã này phải làm gì, nhưng chắc chắn là sai

nếu bạn muốn cấp phát bộ nhớ cho Nsố nguyên

int *num = calloc(N, sizeof(*num));

và để giải phóng bạn chỉ cần

free(num);

Hoặc nếu bạn muốn cấp phát con trỏ để lưu trữ N con trỏ cho N số nguyên

int **allocate(size_t N)
{
    int **num = malloc(N * sizeof(*num));
    for(size_t i=0; i<N; i++)
    {
        num[i] = calloc(N, sizeof(**num));
    }
    return num;
}

void arrayfree(int **num, size_t size)
{
    for(size_t i = 0; i < size; i++)
    {
        free(num[i]);
    }
    free(num);
}

Khi bạn cấp phát bộ nhớ, bạn phải kiểm tra xem hoạt động có thành công hay không. Những kiểm tra đó không được bao gồm trong ví dụ để làm cho mã dễ đọc hơn.

tadman Aug 16 2020 at 09:55

Các hàm calloc()malloc()trả về một con trỏ đến cấp phát mà nó đóng vai trò như một chốt để giải phóng bộ nhớ đó. Mặc dù bạn có thể tự do tạo bản sao của con trỏ đó và thao tác những bản sao đó khi bạn thấy phù hợp, nhưng khi bạn gọi đến, free()bạn phải cung cấp giá trị gốc .

Điều đó có nghĩa là điều này không hoạt động:

// Original allocation
int* x = calloc(42, sizeof(int));

// Making a new (independent) copy of the pointer to a new pointer
int* p = x;

// Arbitrary pointer manipulation and mangling
x++;

// Freeing with the copied value
free(p);

Bạn cũng có thể mạo hiểm một chút, miễn là bạn quay trở lại điểm đến ban đầu:

int* x = calloc(42, sizeof(int));

x += 40;
x -= 30;
x += 10;
x -= 13;
x -= 7;

free(x);

Nơi đây xđã trở lại giá trị ban đầu sau một chặng đường ngắn. Nói chung, tốt hơn hết bạn nên bảo toàn con trỏ gốc hơn là phải tạo lại nó sau này. Tạo bản sao nếu bạn đang có ý định thao túng chúng.