Cấp phát động (Dynamic Memory Allocation) trong C

Cấp phát động – Dynamic Memory Allocation là gì?

Như đã biết, array là một tập hợp một số cố định của các giá trị. Một khi kích thước array được khai báo thì sẽ không được thay đổi.

Thỉnh thoảng kích thước của array đã khai báo không đủ dùng. Để giải quyết vấn đề này, chúng ta có thể phân bổ bộ nhớ một cách thủ công trong quá trình hoạt động. Thủ thuật này được gọi là cấp phát động hay Dynamic Memory Allocation.

Để phân bổ bộ nhớ động, ta dùng các hàm malloc(), calloc(), realloc(), và realloc() được định nghĩa trong tập tin <stdlib.h>.


malloc()

Tên malloc đại diện cho memory allocation.

Hàm malloc() dự trữ một khối bộ nhớ của số byte được chỉ định. Và, nó trả về một pointer rỗng có thể tạo thành các pointer dưới mọi hình thức.

Cú pháp

ptr = (castType*) malloc(size);

Ví dụ

ptr = (float*) malloc(100 * sizeof(float));

Câu lệnh trên đã phân bổ 400 bytes của bộ nhớ bởi sizeof(float)4. Pointer ptr được gán giá trị của địa chỉ của byte đầu tiên trong bộ nhớ được phân bổ.

Kết quả của biểu thức sẽ là NULL nếu bộ nhớ không được phân bổ


calloc()

Tên “calloc” đại diện cho contiguous allocation.

Hàm malloc() phân bổ bộ nhớ và để lại bộ nhớ chưa được khởi tạo. Trong khi đó, hàm calloc() phân bổ bộ nhớ và khởi tạo tất cả các bit về 0.

Cú pháp

ptr = (castType*)calloc(n, size);

Ví dụ

ptr = (float*) calloc(25, sizeof(float));

Câu lệnh trên phân bổ bộ nhớ cho 25 phần tử dạng float.


free()

Bộ nhớ được phân bổ động được tạo bằng calloc() hoặc malloc() không được tự giải phóng. Bạn phải sử dụng free() để giải phóng bộ nhớ.

Cú pháp

free(ptr);

Ví dụ 1 : malloc()

Chương trình tính tổng của n số nhập vào bởi user.

/ Program to calculate the sum of n numbers entered by the user

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n, i, *ptr, sum = 0;

    printf("Nhập số phần tử: ");
    scanf("%d", &n);

    ptr = (int*) malloc(n * sizeof(int));

    // nếu bộ nhớ không được phân bổ
    if(ptr == NULL)                     
    {
        printf("Lỗi! Bộ nhớ không được phân bổ.");
        exit(0);
    }

    printf("Nhập phần tử: ");
    for(i = 0; i < n; ++i)
    {
        scanf("%d", ptr + i);
        sum += *(ptr + i);
    }

    printf("Sum = %d", sum);

    // giải phóng bộ nhớ
    free(ptr);

    return 0;
}

Ví dụ 2: calloc()

Chương trình tương tự ví dụ 1 nhưng dùng hàm calloc()

// Program to calculate the sum of n numbers entered by the user

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n, i, *ptr, sum = 0;
    printf("Enter number of elements: ");
    scanf("%d", &n);

    ptr = (int*) calloc(n, sizeof(int));
    if(ptr == NULL)
    {
        printf("Error! memory not allocated.");
        exit(0);
    }

    printf("Enter elements: ");
    for(i = 0; i < n; ++i)
    {
        scanf("%d", ptr + i);
        sum += *(ptr + i);
    }

    printf("Sum = %d", sum);
    free(ptr);
    return 0;
}

realloc()

Nếu bộ nhớ được cấp phát động không đủ hoặc nhiều hơn mức yêu cầu, bạn có thể thay đổi kích thước của bộ nhớ được phân bổ trước đó bằng cách sử dụng hàm realloc().

Cú pháp

ptr = realloc(ptr, x);

Ví dụ 3: realloc()

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int *ptr, i , n1, n2;
    printf("Nhập size: ");
    scanf("%d", &n1);

    ptr = (int*) malloc(n1 * sizeof(int));

    printf("địa chỉ của bộ nhớ phân bổ trước đó: ");
    for(i = 0; i < n1; ++i)
         printf("%u\n",ptr + i);

    printf("\nNhập size mới: ");
    scanf("%d", &n2);

    // phân bổ lại bộ nhớ
    ptr = realloc(ptr, n2 * sizeof(int));

    printf("địa chỉ của bộ nhớ phân bổ mới: ");
    for(i = 0; i < n2; ++i)
         printf("%u\n", ptr + i);

    free(ptr);

    return 0;
}

Kết quả

Nhập size: 2
địa chỉ của bộ nhớ phân bổ trước đó:
26855472
26855476

Nhập size mới: 4
địa chỉ của bộ nhớ phân bổ mới:
26855472
26855476
26855480
26855484
Series Navigation<< Pointer và hàm trong CString trong C >>

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *