指针和动态内存分配

简介: 指针和动态内存分配

指针和动态内存分配


在C语言中,指针和动态内存分配是编程中非常重要的概念。动态内存分配允许程序在运行时根据需要分配和释放内存。这通过几个标准库函数来实现,包括malloc、calloc、realloc和free。

1. malloc 函数

malloc函数用于分配指定字节数的内存。它返回一个指向所分配内存的指针,如果内存分配失败,则返回NULL。

void *malloc(size_t size);

size:要分配的字节数。

使用示例:

int *ptr = (int *)malloc(sizeof(int) * 10); // 分配一个包含10个整数的数组if (ptr == NULL) {    // 内存分配失败处理}

2. calloc 函数

calloc函数与malloc类似,但calloc会将分配的内存区域初始化为0,并且它还接受两个参数,一个是要分配的元素的数量,另一个是每个元素的大小。

void *calloc(size_t num, size_t size);

 

num:要分配的元素的数量。

 

 

size:每个元素的大小。

 

使用示例:

int *ptr = (int *)calloc(10, sizeof(int)); // 分配一个包含10个整数的数组,并初始化为0if (ptr == NULL) {    // 内存分配失败处理}

3. realloc 函数

realloc函数用于调整已分配内存的大小。它可以增加或减少已分配内存的大小。如果新的大小大于原始大小,则会在内存块的末尾添加额外的内存。如果新的大小小于原始大小,则会释放额外的内存。

void *realloc(void *ptr, size_t size);

 

ptr:指向要调整大小的内存的指针。

 

 

size:新的内存大小(以字节为单位)。

 

使用示例:

int *ptr = (int *)malloc(sizeof(int) * 10);// ... 使用ptr ...ptr = (int *)realloc(ptr, sizeof(int) * 20); // 将内存大小增加到20个整数if (ptr == NULL) {    // realloc失败处理,原始内存仍然有效}

4. free 函数

free函数用于释放之前使用malloc、calloc或realloc分配的内存。

void free(void *ptr);

ptr:指向要释放的内存的指针。

使用示例:

int *ptr = (int *)malloc(sizeof(int) * 10);// ... 使用ptr ...free(ptr); // 释放内存ptr = NULL; // 将指针设置为NULL,避免悬挂指针

注意:在释放内存后,将指针设置为NULL是一个好习惯,这可以防止在后续代码中意外地再次使用已释放的内存(悬挂指针)。

 

 

在C语言中,指针和动态内存分配是编程中至关重要的概念,它们允许程序在运行时根据需要灵活地分配和释放内存空间。这一机制主要通过几个标准库函数实现,包括malloc、calloc、realloc和free。下面将详细解释这些函数的使用,并通过代码示例来展示它们在实际编程中的应用。

1. malloc 函数

malloc(Memory Allocation)函数用于分配指定字节数的内存。它返回一个指向所分配内存的指针,如果内存分配失败,则返回NULL。函数的原型如下:

void *malloc(size_t size);

size:要分配的字节数。

使用示例

假设我们需要分配一个能够存储10个整数的数组,可以使用malloc函数来实现:

#include <stdio.h>

#include <stdlib.h>

 

int main() {

int *ptr;

ptr = (int *)malloc(sizeof(int) * 10); // 分配内存

 

if (ptr == NULL) {

// 处理内存分配失败的情况

printf("Memory allocation failed!\n");

return 1;

}

 

// 使用ptr指向的内存

for (int i = 0; i < 10; i++) {

ptr[i] = i * 2; // 初始化数组

}

 

// 打印数组内容

for (int i = 0; i < 10; i++) {

printf("%d ", ptr[i]);

}

printf("\n");

 

// 释放内存

free(ptr);

ptr = NULL; // 避免悬挂指针

 

return 0;

}

2. calloc 函数

calloc(Contiguous Allocation)函数与malloc类似,但它有两个参数:一个是要分配的元素的数量,另一个是每个元素的大小。此外,calloc会将分配的内存区域初始化为0。函数的原型如下:

void *calloc(size_t num, size_t size);

num:要分配的元素的数量。

size:每个元素的大小。

使用示例

继续使用之前的例子,但这次我们使用calloc来分配并初始化一个包含10个整数的数组:

#include <stdio.h>

#include <stdlib.h>

 

int main() {

int *ptr;

ptr = (int *)calloc(10, sizeof(int)); // 分配并初始化内存

 

if (ptr == NULL) {

// 处理内存分配失败的情况

printf("Memory allocation failed!\n");

return 1;

}

 

// 使用ptr指向的内存(此时数组已自动初始化为0)

for (int i = 0; i < 10; i++) {

ptr[i] = i * 2; // 修改数组内容

}

 

// 打印数组内容

for (int i = 0; i < 10; i++) {

printf("%d ", ptr[i]);

}

printf("\n");

 

// 释放内存

free(ptr);

ptr = NULL; // 避免悬挂指针

 

return 0;

}

3. realloc 函数

realloc(Re-Allocation)函数用于调整已分配内存的大小。如果新的大小大于原始大小,则会在内存块的末尾添加额外的内存;如果新的大小小于原始大小,则会释放额外的内存。函数的原型如下:

void *realloc(void *ptr, size_t size);

ptr:指向要调整大小的内存的指针。

size:新的内存大小(以字节为单位)。

使用示例

假设我们已经有了一个包含10个整数的数组,现在需要将其扩展到20个整数:

#include <stdio.h>

#include <stdlib.h>

 

int main() {

int *ptr;

ptr = (int *)malloc(sizeof(int) * 10); // 初始分配

 

if (ptr == NULL) {

// 处理内存分配失败的情况

printf("Memory allocation failed!\n");

return 1;

}

 

// 假设这里已经使用了ptr指向的内存

 

// 调整内存大小

ptr = (int *)realloc(ptr, sizeof(int) * 20);

if (ptr == NULL

 

目录
相关文章
|
7月前
|
存储 Java C++
C++ 引用和指针:内存地址、创建方法及应用解析
C++中的引用是现有变量的别名,创建时需用`&`运算符,如`string &meal = food;`。指针存储变量的内存地址,使用`*`创建,如`string* ptr = &food;`。引用必须初始化且不可为空,而指针可初始化为空。引用在函数参数传递和提高效率时有用,指针适用于动态内存分配和复杂数据结构操作。选择使用取决于具体需求。
98 9
|
7月前
|
存储 Go iOS开发
掌握Go语言:探索Go语言指针,解锁高效内存操作与动态数据结构的奥秘(19)
掌握Go语言:探索Go语言指针,解锁高效内存操作与动态数据结构的奥秘(19)
|
7月前
|
安全 程序员 C++
C++中的智能指针:从原始指针到现代内存管理
C++中的智能指针:从原始指针到现代内存管理
53 0
|
7月前
|
安全 C++ 容器
C++中的智能指针:自动内存管理的利器
C++中的智能指针:自动内存管理的利器
89 0
|
11天前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
57 12
|
4月前
|
存储 安全 Go
Go 中的指针:了解内存引用
Go 中的指针:了解内存引用
|
5月前
|
运维
开发与运维数组问题之指针的加减法意义如何解决
开发与运维数组问题之指针的加减法意义如何解决
45 7
|
5月前
|
存储 C++ 运维
开发与运维数组问题之指针的定义语法如何解决
开发与运维数组问题之指针的定义语法如何解决
35 6
|
6月前
|
C++ 存储 Java
C++ 引用和指针:内存地址、创建方法及应用解析
'markdown'C++ 中的引用是现有变量的别名,用 `&` 创建。例如:`string &meal = food;`。指针通过 `&` 获取变量内存地址,用 `*` 创建。指针变量存储地址,如 `string *ptr = &food;`。引用不可为空且不可变,指针可为空且可变,适用于动态内存和复杂数据结构。两者在函数参数传递和效率提升方面各有优势。 ```
|
5月前
|
存储 安全 程序员