动态内存分配的C代码示例

概述
之前有同学在QQ上问我,C语言中的动态内存分配是怎么回事。

首先,我们来看看内存分配的概念,它是指在程序执行的过程中分配或者回收存储空间的方法。一般说来,内存分配方法分为静态内存分配和动态内存分配两种。在本文中,我们主要讨论动态内存分配。
要实现动态内存分配,就需要有执行这个操作的对象。C语言考虑得很周到,它为我们提供的两个标准库函数:malloc和free。

malloc和free函数简介
malloc函数
原型:void *malloc(size_t size);
简介:该函数在内存的动态存储区中分配一块长度为size字节的连续区域;如果分配成功,则函数的返回值为该区域的首地址;如果分配失败,则返回空指针值NULL。

free函数
原型:void free(void *ptr);
简介:该函数将之前用malloc开辟的内存空间释放掉,无返回值。

从形式上看,malloc和free函数都非常的简单,只有一个输入参数。下面,我们用具体的C代码来演示它们的用法。

C代码示例

/**********************************************************************
* 版权所有(C)2016, Zhou Zhaoxiong
*
* 文件名称:DynamicMemoryAlloc.c
* 文件标识:无
* 内容摘要:示例动态内存分配
* 其它说明:无
* 当前版本:V1.0
* 作   者:ZhouZhaoxiong
* 完成日期:20160901
*
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>

// 重定义数据类型
typedef signed   int    INT32;
typedef signed   char   INT8;

/****************************************************************
* 功能描述: 主函数
* 输入参数: 无
* 输出参数: 无
* 返回值: 0-执行成功  -1-执行失败
* 其他说明: 无
* 修改日期        版本号         修改人          修改内容
*-------------------------------------------------------------
* 20160901       V1.0     Zhou Zhaoxiong       创建
****************************************************************/
INT32 main(void)
{
   INT8  szStrBuf[100] = {0};
   INT8 *pStr          = NULL;

   // 为指针变量分配内存
   pStr = malloc(100);
   if (NULL == pStr)    // 分配失败
   {
       printf("pStr is NULL!\n", pStr);
       return -1;
   }
   memset(pStr, 0x00, 100);

   // 打印初始化变量的值
   printf("Step1: StrBuf=%s, pStr=%s\n", szStrBuf, pStr);

   // 给变量赋值
   memcpy(szStrBuf, "abcdefg", strlen("abcdefg"));
   memcpy(pStr, "1234567", strlen("1234567"));

   // 打印赋值之后的变量的值
   printf("Step2: StrBuf=%s, pStr=%s\n", szStrBuf, pStr);

   // 释放动态内存
   free(pStr);
   pStr = NULL;

   // 打印释放动态内存之后的变量的值
   printf("Step3: StrBuf=%s, pStr=%s\n", szStrBuf, pStr);

   // --------------------

   // 重新为指针变量分配内存
   pStr = malloc(50);
   if (NULL == pStr)    // 分配失败
   {
       printf("pStr is NULL!\n", pStr);
       return -1;
   }
   memset(pStr, 0x00, 50);

   // 给变量赋值
   memcpy(szStrBuf, "abcdefg", strlen("abcdefg"));
   pStr = szStrBuf+1;

   // 打印重新分配动态内存之后的变量的值
   printf("Step4: StrBuf=%s, pStr=%s\n", szStrBuf, pStr);

   // 再次释放动态内存
   free(pStr);
   pStr = NULL;

   // 打印再次释放动态内存之后的变量的值
   printf("Step5: StrBuf=%s, pStr=%s\n", szStrBuf, pStr);

   return 0;
}

程序编译及运行
将上面编写的DynamicMemoryAlloc.c文件上传到Linux机器上,执行“gcc -g -oDynamicMemoryAlloc DynamicMemoryAlloc.c”命令,生成DynamicMemoryAlloc文件,然后执行“DynamicMemoryAlloc”命令,程序运行结果如下:

Step1: StrBuf=, pStr=
Step2: StrBuf=abcdefg, pStr=1234567
Step3: StrBuf=abcdefg, pStr=(null)
Step4: StrBuf=abcdefg, pStr=bcdefg
Step5: StrBuf=abcdefg, pStr=(null)

程序说明
第一,在main函数中,我们定义了两个变量:szStrBuf和pStr,其中szStrBuf在定义的时候已经给出了其占用内存空间的大小,因此该变量为静态内存分配;pStr变量在需要使用到的时候才分配内存,因此该变量为动态内存分配。

第二,我们使用malloc函数为变量分配动态内存,并使用free函数来释放动态内存,这两个函数要成对出现(即有一个malloc函数,就会有一个与之对应的free函数)。

第三,进行动态内存分配的变量的一个使用周期是在malloc函数和free函数之间,当一个变量的动态内存被释放掉之后,如果重新为它分配动态内存,那么它还是可以正常使用;例如,在main函数中,pStr变量先是被分配了100字节的空间,使用完成之后该空间就被释放掉了,当第二次为它分配50字节空间的时候,它又可以照常被使用了。

第四,从上面的代码可以看到,为进行动态内存分配的变量赋值的方式有两种,第一种是使用memcpy等函数进行赋值(如代码中的memcpy(pStr, “1234567”,strlen(“1234567”));),第二种是用另一个变量直接为它赋值(如代码中的pStr = szStrBuf+1;)。

总结
内存操作在C语言中占有非常重要的地位,而动态内存分配不当又是一个导致程序出现问题的主要原因之一。从本文中的代码可以看到,动态内存分配其实也没有什么特别困难之处,只要在需要用到某变量的时候为它分配一定的内存空间,在使用完成之后将该空间释放掉就行了。最为重要的是,malloc和free函数一定要配对出现。

最后再来举一个例子。上大学的时候,很多同学的生活费都是由家里给,有的家长在一学期或一学年开始的时候,就把整个学期或学年的生活费打到了卡上,而有的家长是按月打生活费的。这里的按学期或学年打生活费就相当于静态内存分配,而按月打生活费就相当于动态内存分配。

时间: 2025-01-03 07:29:36

动态内存分配的C代码示例的相关文章

指针-一个动态内存分配的问题,函数执行后p指向哪里?

问题描述 一个动态内存分配的问题,函数执行后p指向哪里? 一下是我的代码: #include<stdio.h> #include<stdlib.h> #include<string.h> char *strcnp(char *sd,char *ds) { char *q=sd; while((*ds++=*sd++)!='') NULL; return q; } int main() { char *a[4]={"abc","def&quo

函数参数传递和动态内存分配的问题

问题描述 函数参数传递和动态内存分配的问题 利用下面这段代码进行动态内存分配有什么问题: char *getmemory(int sum) { char *p=NULL; p=(char *)malloc(sum); return p; } int main() { char *str=NULL; str=getmemory(100); strcpy(str,"hello c!"); printf("%sn",str); } 解决方案 你的主程序需要释放内存,否则可

(一四二)继承和动态内存分配

当基类.派生类用,或者不用动态内存时,共有四种情况: (注意,前提是基类的动态内存分配相关函数符合常规使用动态内存的要求)   情况一:基类 使用 动态内存分配.派生类新增数据成员 不使用 动态内存分配 假如基类使用动态内存分配(new),其必然设定①构造函数.②复制构造函数.③赋值运算符.④析构函数. 又知,派生类的构造函数(包括默认构造函数),需要调用基类的构造函数. 那么基类的数据成员若使new,则已经没问题. 派生类新增的数据成员,由于不使用new,因此可以按值传递.   ①对于派生类构

C语言 动态内存分配的详解及实例_C 语言

1. 动态内存分配的意义 (1)C 语言中的一切操作都是基于内存的. (2)变量和数组都是内存的别名.     ①内存分配由编译器在编译期间决定     ②定义数组的时候必须指定数组长度     ③数组长度是在编译期就必须确定的 (3)但是程序运行的过程中,可能需要使用一些额外的内存空间 2. malloc 和 free 函数 (1)malloc 和 free 用于执行动态内存分配的释放 (2)malloc 所分配的是一块连续的内存 (3)malloc 以字节为单位,并且返回值不带任何的类型信息

C++语言之动态内存分配

在C语言中,我们熟悉的内存分配与释放的最常用的接口分别是malloc , free .在C++中:     存在着更加方便的动态存储分配: 1.new 和delete 机制,new 它能更可靠控制存储区的分配,C++ 用delete 释放new 运算符申请的存储区. 2.new 分配空间时, 如果是对象, 自动调用构造函数. 3.new [] 表示分配一个动态数组, 要跟delete [] 配合使用. 直接上代码: #include <iostream> using namespace std

动态为事件添加js代码示例_javascript技巧

复制代码 代码如下: <HTML> <HEAD> <script language="javascript"> attachEvent("onblur", blur); function blur() { document.all.form.username.attachEvent("onblur", blur); if(event.srcElement == document.all.form.usernam

浅析动态内存分配Malloc二元操作性能教程

在浅析之前先看下 malloc的原型: void* malloc(size_t size); 这里唯一需要注意到是: typedef unsigned int size_t; 来段测试程序 #include < stdio.h > int main(int argc, char * argv[]) {  int i = 0;  for (; i < 100; i++) {   malloc(32);   /**< 每次malloc 32 字节 */  }  return 0; }

语言变量声明内存分配

一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.程序结束时由编译器自动释放. 2.堆区(heap) - 在内存开辟另一块存储区域.一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵. 3.全局区(静态区)(static)-编译器编译时即分配内存.全局变量和静态变量的存储是放在一块的,初始化的全局

深入解析C语言中的内存分配相关问题_C 语言

C内存分配区域 程序代码区存放函数体的二进制代码 全局数据区全局变量和静态变量的存储是放在一起的.初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域.常量数据存放在另一个区域里.这些数据在程序结束后由系统释放.我们所说的BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称 栈区由编译器自动分配释放,存放函数的参数值,局部变量的值等.其操作方式类似于数据