malloc在c语言中的用法(非常详细)

malloc在c语言中的用法(非常详细)

malloc() 是 C语言中的一个内存分配函数,用于在内存上分配指定大小的连续内存空间。

malloc() 函数是 C语言中动态内存管理的核心函数之一,使用 malloc() 函数分配的内存在函数返回后不会被自动释放,因此需要在适当的时候手动释放内存,以防止内存泄漏。

函数 malloc 的原型如下:

void* malloc(size_t size);

参数 size 表示要分配的内存大小,以字节为单位。通常使用 sizeof 操作符确定数据类型的大小。

如果内存分配成功,那么 malloc() 函数将返回一个指向新分配内存的指针(void* 类型)。如果内存分配失败(例如,请求的内存大小超过可用内存),那么 malloc() 函数将返回 NULL。

我们一旦通过 malloc() 函数成功地申请了内存空间,就可以根据需要将返回的指针转为任意类型的指针。只要通过指针访问内存,就不能超过这段内存空间的大小。

下面是一个使用 malloc() 函数的示例:

#include

#include

int main()

{

int *pInt = NULL;

pInt = malloc(sizeof(int));

double *pDouble = NULL;

pDouble = malloc(sizeof(double));

*pInt = 123;

*pDouble = 3.1415926;

printf("%d %f", *pInt, *pDouble);

return 0;

}

运行结果为:

123 3.141593

malloc(sizeof(int)) 申请了 4 字节的内存空间,若申请成功,它将返回一个 void* 类型的指针,其数值为成功申请的内存空间的首地址。我们可以把这 4 字节的内存空间用于存储 int 类型的数据,只需通过赋值将 void* 转换为 int*,然后对 int* 类型的指针进行取值,接着将该值赋值给该指针。

同样,malloc(sizeof(double)) 申请了 8 字节的内存空间,若申请成功,它将返回一个 void* 类型的指针,其数值为成功申请的内存空间的首地址。我们可以把这 8 字节的内存空间用于存储 double 类型的数据,只需通过赋值将 void* 转换为 double*,然后对 double* 类型的指针进行取值,接着将该值赋值给该指针。

在 C语言中,void * 可以通过赋值转换为其他类型的指针:

int *pInt = NULL;

pInt = malloc(sizeof(int));

double *pDouble = NULL;

pDouble = malloc(sizeof(double));

另外,一定要严格保证使用指针访问成功申请的内存空间时,不要超过申请时预定的空间大小,例如:

double *pDouble = NULL;

pDouble = malloc(sizeof(int));

*pDouble = 3.1415926;

上面的代码申请了 sizeof(int),即 4 字节大小的空间。若申请成功,它将返回一个 void* 类型的指针,其数值为成功申请的内存空间的首地址。接着,我们把它转换为 double* 类型的指针,并赋值给 pDouble。

但是,若对 pDouble 指针使用取值运算符 *,将访问从首地址开始的 8 字节的内存空间,超出了申请时预定的 4 字节空间,这种做法可能导致程序崩溃。

若需要动态地创建一个有 10 个 int 元素的数组,那么需要申请 sizeof(int) * 10 字节的内存空间,或者也可以写成 sizeof(int[10])。

int *pArr = NULL;

// 申请sizeof(int) * n,转换为int *使用

pArr = malloc(sizeof(int) * 10);

// 给数组元素赋值

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

pArr[i] = i;

// 输出数组元素

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

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

之前讨论的都是 malloc() 函数成功申请到内存的情况,作为一个稳健的程序应当也考虑失败的情况。若 malloc() 函数申请内存空间失败,它将返回 NULL。为 NULL 指针取值将导致程序崩溃。建议每次通过 malloc() 函数申请内存空间时都对返回值进行判断:

int *pInt = NULL;

pInt = malloc(sizeof(int));

// 判断malloc函数是否成功申请了内存空间

if (pInt != NULL)

{

// 若不为NULL,则再次使用这个指针

*pInt = 123;

printf("%d", *pInt);

}

C语言释放内存空间

在使用 malloc() 函数申请内存空间并完成使用后,务必记得使用 free() 函数对这段内存空间进行释放。

free() 是 C语言中用于释放之前通过 malloc() 函数分配的内存空间的内存释放函数。free() 函数也是 C语言中动态内存管理的核心函数之一。当不再需要使用动态分配的内存时,调用 free() 函数将内存归还给操作系统,以避免内存泄漏。

函数 free() 的原型如下:

void free (void* ptr);

参数 ptr 表示指向要释放的内存块的指针。这个指针应该是之前由 malloc() 函数返回的指针。如果传递给 free() 函数的指针不是这个函数返回的指针,或者已经被释放过,将导致未定义行为。

注意事项:

如果 ptr 是 NULL,则 free() 函数不执行任何操作。

尝试释放已经释放过的内存(称为双重释放)将导致未定义行为。

使用 free() 函数释放内存后,不要再次访问已释放的内存区域。

以下是一个使用 malloc() 函数和 free() 函数的简单示例:

int *pInt = NULL;

pInt = malloc(sizeof(int));

if (pInt != NULL)

{

*pInt = 123;

printf("%d", *pInt);

// 释放内存空间

free(pInt);

}

上述代码申请了 sizeof(int) 字节内存空间,用作 int 类型。内存使用完毕后,我们利用 free() 函数对内存空间进行释放。free() 函数的参数是 void* 类型的指针,而 void* 类型的指针可以接收任何类型的指针。因此,我们可以直接将 pInt 传递给 free() 函数,无须进行类型转换。

如果仅调用 malloc() 函数申请内存空间,而未调用 free() 函数释放内存空间,则成功申请的内存空间将保留直至程序结束。这期间程序所占用的内存空间会逐渐增大,直至无可分配空间,无法再成功申请内存空间。

下面展示了一个未释放内存的示例:

#include

#include

int main()

{

while (1)

{

void* p = malloc(1024 * 1024);

printf("%d\n", p);

}

return 0;

}

这种情况通常是由于申请了内存空间,但忘记释放内存空间导致的。应及时释放不再使用的内存空间。

上面程序中,申请的内存空间首地址存储在指针 p 中,下一次新申请的内存空间首地址会覆盖上一次的首地址。由于没有保存内存空间的首地址,因此程序将无法再通过任何方式使用或释放这些内存空间,这种现象被称为内存泄漏。具有内存泄漏问题的代码若长时间运行,会导致程序所占用的内存空间逐渐增大,直至没有可分配的内存空间,并无法再成功申请内存空间。

相关推荐