C语言之内存分区与动态数组

 

一.内存的动态分配

内存区包括:栈区、堆区、全局区或静态区、代码区;

栈区(stack)是由编译器自动分配释放,存放函数调用、参数值、局部变量的值等;

//栈区分析
#include<stdio.h>
char* getstr()
{
    //函数结束后栈区内存释放
	char str[] = "abcdef";
	printf("str = %s\n",str);
	return str;
}
int main()
{
	char buf[128] = {0};
    //strcpy(buf, getstr())
    //printf("buf = %s\n", buf);
	
	char *p;
	p=getstr();
	printf("p = %s\n", p);        //乱码,不确定
	
	return 0;
}

堆区(heap)是一般由程序员分配释放,C语言允许建立内存动态分配区域,以存放一些临时数据的自由存储区;

//堆区分析
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* getstr()
{
	char *str = (char *)malloc(100);
	if(str == NULL)
		return NULL;
	strcpy(str,"abcdef");
	return str;
}
int main()
{
	char buf[128] = {0};
    //strcpy(buf, getstr())
	//printf("buf = %s\n", buf);
	
	char *p = NULL, *q;
	p=getstr();
	if(p != NULL)
	{
		q=p;
		printf("p = %s\n", p);
		//p指针释放前后指向没有变化
		printf("p = %d\n", p);
		free(p);
		printf("p = %d\n", p);
	}
	p = NULL;	
	return 0;
}

全局区静态区(static)是全局变量和静态变量的存储区,初始化和未初始化分开放置;字符串常量和其他常量的存储位置,程序结束后由操作系统释放;

//全局变量区分析,相同字符串常量地址相同
#include<stdio.h>
char* getstr1()
{
	char* p = "abcdef";
	return p;
}
char* getstr2()
{
	char* q = "abcdef";
	return q;
}
int main()
{
	char* p=NULL;
	char* q=NULL;
	
	p=getstr1();
	q=getstr2();
	//p,q地址相同
	printf("p = %s, p = %d\n",p,p);
	printf("q = %s, q = %d\n",q,q);

}

代码区:存储函数体的二进制代码。

内存的动态分配是通过系提供的库函数实现的,主要有malloccallocfreerealloc这4个函数。

malloc函数原型为 void *malloc(unsigned int size);其作用是在内存的动态储存区中分配一个长度为size的连续空间。形参size的类型定为无符号整型(不允许是负数)。此函数的值是分配区域的第一个字节的地址。如果此函数未能程成功的执行则返回空指针NULL。

calloc函数原型为 void *calloc(unsigned n,unsigned size); 其作用是在内存的动态储存区中分配n个长度为size的连续空间,足以保存数组。函数返回指向所分配区域的起始位置的指针,如果分配不成功,返回NULL。

free函数原型为 void free(void *p);其作用是释放变量p所指向的动态空间。

  • free只是释放了malloc所申请的内存,并没有改变指针的值;
  • 由于指针所指向的内存空间已经被释放,所以其他代码有机会改写其中的内容,相当于该指针从此指向了自己无法控制的区域;
  • 为了避免错误,所以最好在free之后,使指针指向NULL;

根据原理的解释分析:free函数的作用只是告诉操作系统该内存不用了,可以收回,操作系统就把该内存链接到链接表上,

但是这段内存用户还是可以访问到的,只是该内存的值可能已经发生了变化。
 

realloc函数原型为 void *realloc(void *p,unsigned int size);将已经通过malloc函数或calloc函数获得的动态空间重新分配

以上函数声明需要#include<stdlib.h>头文件声明。

二.动态数组实现

一维动态数组实现

    //一次性分配数组
    int *array,N;                            //定义指针及数组个数
    array = (int *)malloc(sizeof(int)*N)       //动态分配一维数组
    //未知数组个数,多次分配数组
    str = (char*)malloc(sizeof(char));         
    str = (char*)realloc(str, sizeof(char)*n);  //重新分配
    
    //释放内存,指针指向并没有变
    free(str);
    str = NULL;

二维动态数组实现

    //calloc实现  
    int M,N	                               
    array=(int **)calloc(M,sizeof(int*));       
    for(i=0;i<M;i++)
	    array[i]=(int *)calloc(N,sizeof(int));
    //malloc实现
    int M,N	                               
    array=(int **)malloc(sizeof(int *)*M);       
    for(i=0;i<M;i++)
	    array[i]=(int *)malloc(sizeof(int)*N);

    //释放内存
    for(i = 0; i < n; i++)
    {
        if(array[i])
        {
            free(array[i]);
            array[i] = NULL;
        }    
    }
    if(array)
    {
        free(array[i]);
        array = NULL;
    }

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首次适应算法是一种内存分配算法,它从空闲分区链的起始位置开始查找,找到第一个能够满足作业需要的空闲分区进行分配。下面是一个C语言实现的示例代码: ```c #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 // 内存分区结构体 typedef struct { int start; // 起始地址 int size; // 大小 int status; // 状态,0表示空闲,1表示已分配 } Partition; Partition memory[MAX_SIZE]; // 内存分区数组 int partitionNum = 0; // 内存分区数量 // 初始化内存分区 void initMemory() { memory[0].start = 0; memory[0].size = MAX_SIZE; memory[0].status = 0; partitionNum = 1; } // 显示内存分配情况 void showMemory() { printf("Memory allocation status:\n"); for (int i = 0; i < partitionNum; i++) { printf("Partition %d: start=%d, size=%d, status=%d\n", i, memory[i].start, memory[i].size, memory[i].status); } } // 分配内存 void allocateMemory(int jobSize) { int i; for (i = 0; i < partitionNum; i++) { if (memory[i].status == 0 && memory[i].size >= jobSize) { // 找到第一个空闲分区 break; } } if (i == partitionNum) { // 没有找到合适的分区 printf("No available partition for job with size %d\n", jobSize); return; } if (memory[i].size == jobSize) { // 分区大小刚好等于作业大小 memory[i].status = 1; } else { // 分区大小大于作业大小,需要拆分分区 Partition newPartition; newPartition.start = memory[i].start; newPartition.size = jobSize; newPartition.status = 1; memory[i].start += jobSize; memory[i].size -= jobSize; for (int j = partitionNum; j > i; j--) { // 插入新分区 memory[j] = memory[j - 1]; } memory[i + 1] = newPartition; partitionNum++; } printf("Job with size %d allocated to partition %d\n", jobSize, i); } // 回收内存 void freeMemory(int partitionIndex) { if (memory[partitionIndex].status == 0) { // 分区未分配 printf("Partition %d is not allocated\n", partitionIndex); return; } memory[partitionIndex].status = 0; // 合并相邻的空闲分区 if (partitionIndex > 0 && memory[partitionIndex - 1].status == 0) { memory[partitionIndex - 1].size += memory[partitionIndex].size; for (int i = partitionIndex; i < partitionNum - 1; i++) { memory[i] = memory[i + 1]; } partitionNum--; partitionIndex--; } if (partitionIndex < partitionNum - 1 && memory[partitionIndex + 1].status == 0) { memory[partitionIndex].size += memory[partitionIndex + 1].size; for (int i = partitionIndex + 1; i < partitionNum - 1; i++) { memory[i] = memory[i + 1]; } partitionNum--; } printf("Partition %d freed\n", partitionIndex); } int main() { initMemory(); showMemory(); allocateMemory(20); showMemory(); allocateMemory(30); showMemory(); allocateMemory(10); showMemory(); freeMemory(1); showMemory(); freeMemory(0); showMemory(); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值