亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> C语言

在 C 中使用 malloc()、calloc() 函数进行动态内存分配

在学习 C 动态内存分配之前,我们先了解一下:

C 中的内存管理是如何工作的?

当您使用基本数据类型声明变量时,C 编译器会自动在称为 stack 的内存池中为变量分配内存空间 .

例如,一个浮点变量在声明时通常占用 4 个字节(根据平台)。我们可以使用 sizeof 来验证这些信息 运算符如下例所示

#include <stdio.h>
int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}

输出将是:

 The size of float is 4 bytes

此外,一个指定大小的数组被分配在连续的内存块中,每个块都有一个元素的大小:

#include <stdio.h>
int main() { float arr[10];
printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;}


结果是:

 The size of the float array with 10 element is 40

到目前为止,在声明基本数据类型或数组时,内存是自动管理的。但是,在 C 语言中有一个分配内存的过程,它允许您实现一个数组大小未确定的程序,直到您运行程序(运行时)。这个过程称为“动态内存分配 。”

在本教程中,您将学习-

C 中的动态内存分配

动态内存分配 是根据您的编程需要手动分配和释放内存。动态内存由指向新分配的内存空间的指针管理和服务,这些指针指向我们称为堆的区域中的新分配内存空间。

现在,您可以在运行时动态创建和销毁元素数组,而不会出现任何问题。综上所述,自动内存管理使用栈,C动态内存分配使用堆。

库具有负责动态内存管理的函数。

功能 目的 malloc() 分配请求大小的内存并返回指向
已分配空间的第一个字节的指针。calloc() 为数组元素分配空间。将元素初始化为零并返回指向内存的指针。realloc() 用于修改之前分配的内存空间大小。Free() 释放或清空先前分配的内存空间。

让我们用他们的应用来讨论上面的函数

C语言中的malloc()函数

C malloc() 函数代表内存分配。它是一个用于动态分配内存块的函数。它保留指定大小的内存空间并返回指向内存位置的空指针。返回的指针通常是 void 类型。这意味着我们可以将 C malloc() 函数分配给任何指针。

malloc() 函数语法:

ptr = (cast_type *) malloc (byte_size);

在这里,

malloc() 示例:

Example: ptr = (int *) malloc (50)

这条语句执行成功后,会预留50字节的内存空间。保留空间第一个字节的地址分配给int类型的指针ptr。

再举个例子:

#include <stdlib.h>
int main(){
int *ptr;
ptr = malloc(15 * sizeof(*ptr)); /* a block of 15 integers */
    if (ptr != NULL) {
      *(ptr + 5) = 480; /* assign 480 to sixth integer */
      printf("Value of the 6th integer is %d",*(ptr + 5));
    }
}

输出:

Value of the 6th integer is 480

  1. 注意 sizeof(*ptr) 被用来代替 sizeof(int) 为了在以后将 *ptr 声明类型转换为不同的数据类型时使代码更加健壮。
  2. 如果内存不足,分配可能会失败。在这种情况下,它返回一个 NULL 指针。因此,您应该包含检查 NULL 指针的代码。
  3. 请记住,分配的内存是连续的,可以视为一个数组。我们可以使用指针算法来访问数组元素,而不是使用括号 []。我们建议使用 + 来引用数组元素,因为使用增量 ++ 或 +=会更改指针存储的地址。

malloc() 函数还可以与字符数据类型以及结构等复杂数据类型一起使用。

C 中的 free() 函数

变量的内存在编译时自动释放。在动态内存分配中,您必须显式地释放内存。如果不这样做,您可能会遇到内存不足的错误。

free() 在 C 中调用函数来释放/释放内存。通过释放程序中的内存,您可以让更多的内存供以后使用。

例如:

#include <stdio.h>
int main() {
int* ptr = malloc(10 * sizeof(*ptr));
if (ptr != NULL){
  *(ptr + 2) = 50;
  printf("Value of the 2nd integer is %d",*(ptr + 2));
}
free(ptr);
}

输出

 Value of the 2nd integer is 50

C 中的 calloc() 函数

C calloc() 函数代表连续分配。该函数用于分配多个内存块。它是一个动态内存分配函数,用于将内存分配给复杂的数据结构,如数组和结构。

malloc() 函数用于分配单个内存空间块,而 C 中的 calloc() 用于分配多个内存空间块。 calloc() 函数分配的每个块大小相同。

calloc() 函数语法:

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

每当出现内存不足等内存空间分配错误时,就会返回一个空指针。

calloc() 示例:

下面的程序计算一个等差数列的和。

#include <stdio.h>
    int main() {
        int i, * ptr, sum = 0;
        ptr = calloc(10, sizeof(int));
        if (ptr == NULL) {
            printf("Error! memory not allocated.");
            exit(0);
        }
        printf("Building and calculating the sequence sum of the first 10 terms \ n ");
        for (i = 0; i < 10; ++i) { * (ptr + i) = i;
            sum += * (ptr + i);
        }
        printf("Sum = %d", sum);
        free(ptr);
        return 0;
    }

结果:

Building and calculating the sequence sum of the first 10 terms
Sum = 45

calloc() 与 malloc():主要区别

以下是 C 中 malloc() 与 calloc() 之间的主要区别:

calloc() 函数通常比 malloc() 函数更合适、更高效。虽然这两个函数都用于分配内存空间,但 calloc() 可以一次分配多个块。您不必每次都请求内存块。 calloc()函数用于需要较大内存空间的复杂数据结构中。

C 中的 calloc() 分配的内存块总是初始化为零,而在 C 中的函数 malloc() 中,它总是包含一个垃圾值。

C语言中的realloc()函数

使用 C realloc() 功能,您可以向已分配的内存添加更多内存大小。它扩展当前块,同时保留原始内容。 C中的realloc()代表内存的重新分配。

realloc() 也可以用来减少之前分配的内存大小。

realloc() 函数语法:

ptr = realloc (ptr,newsize);

上述语句在变量newsize中分配了一个指定大小的新内存空间。函数执行后,指针会返回到内存块的第一个字节。新的大小可以比以前的内存更大或更小。我们不能确定新分配的块是否会指向与前一个内存块相同的位置。此功能将复制新区域中的所有先前数据。它确保数据将保持安全。

realloc() 示例:

#include <stdio.h>
int main () {
   char *ptr;
   ptr = (char *) malloc(10);
   strcpy(ptr, "Programming");
   printf(" %s,  Address = %u\n", ptr, ptr);

   ptr = (char *) realloc(ptr, 20); //ptr is reallocated with new size
   strcat(ptr, " In 'C'");
   printf(" %s,  Address = %u\n", ptr, ptr);
   free(ptr);
   return 0;
}

每当 C 中的 realloc() 导致操作不成功时,它都会返回一个空指针,并且之前的数据也被释放。

C 中的动态数组

C 中的动态数组允许元素的数量根据需要增加。 C动态数组广泛应用于计算机科学算法中。

在下面的程序中,我们在 C 中创建并调整了一个动态数组

#include <stdio.h>
    int main() {
        int * arr_dynamic = NULL;
        int elements = 2, i;
        arr_dynamic = calloc(elements, sizeof(int)); //Array with 2 integer blocks
        for (i = 0; i < elements; i++) arr_dynamic[i] = i;
        for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
        elements = 4;
        arr_dynamic = realloc(arr_dynamic, elements * sizeof(int)); //reallocate 4 elements
        printf("After realloc\n");
        for (i = 2; i < elements; i++) arr_dynamic[i] = i;
        for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
        free(arr_dynamic);
    }

C动态数组程序在屏幕上的结果:

 
arr_dynamic[0]=0
arr_dynamic[1]=1
After realloc
arr_dynamic[0]=0
arr_dynamic[1]=1
arr_dynamic[2]=2
arr_dynamic[3]=3

总结


C语言

  1. 只读存储器 (ROM)
  2. C# 基本输入和输出
  3. C# 使用
  4. C++ 内存管理:新建和删除
  5. C 编程中用户定义函数的类型
  6. C 动态内存分配
  7. C 标准库函数
  8. C++ 动态分配数组的例子
  9. 带有程序示例的 C++ 函数
  10. C - 函数
  11. C - 内存管理
  12. C++ 动态内存