C语言——动态内存分配

传统数组的缺点

        1.数组的长度必须事先指定,且必须是常整数,不能是变量。

        例子:

                int a[5];   //OK

                int len = 5; int a[len];    //Error

        2.传统形式定义的数组,该数组的内存程序员无法释放

          在一个函数运行期间,系统为该函数中数组分配的空间会一直存在,直到该函数运行结束,数组的空间才会被释放。

        3.数组的长度一旦定义,其长度就不能在改变

           数组的长度不能在函数运行的过程中动态的扩充或缩小。

         4.A函数定义的数组,在A函数运行期间可以被其他函数调用,A函数终止后不能被其他函数所调用。

            传统方式定义的数组不能跨函数使用。

       

malloc函数的简单使用

     使用前需要加载头文件 #include<stdlib.h>

#include<stdio.h>
#include<malloc.h>

/*
	malloc是memory(内存)allocate(分配)的缩写 
*/


int main(){
	int  i = 5;  // 分配了四个字节,静态分配
	int * p = (int *)malloc(4);
		/*
			1.要使用malloc函数,必须添加malloc.h这个头文件
			2.malloc函数只有一个形参,并且形参是整形
			3.形参的整形,表示请求系统为本程序分配4个字节
			4.malloc函数只能返回第一个字节的地址 
			5.11行分配了12个字节,p占8个字节,p所指向的内存占了4个字节
			6.p本身所占的内存是静态分配的,p所指向的内存是动态分配的 
		*/
		
		
		*p = 5;   // *p代表的就是一个int变量,只不过*p 这个整型变量的内存分配和第10行的方式不同 
		free(p);  // 表示把p所指向的内存给释放掉,p本身只能在所在函数运行结束时由系统释放 
		 
	
	return 0;
	
	
} 

         这行代码需要进行深入理解。

动态内存分配举例——动态数组的构造

        静态数组的分配

        int a [5];         // 如果int占4个字节,则本数组共包含20个字节,每4个字节被当作一个int变量来使用 

#include<stdio.h>
#include <malloc.h> 


int main(){
	int a[5];		// 如果int占4个字节,则本数组共包含20个字节,每4个字节被当作一个int变量来使用 
	int len;
	int  * pArr;
	
	printf("请输入要存放的元素的个数:");
	scanf("%d", & len);   
	
	pArr = (int *)malloc(sizeof(int) * 5);
	// 上一行动态构造了一个一维数组,该一维数组的长度是len, 类似于 int pArr[len]; 
//	pArr[1] = 12;
//	printf("%d", *(pArr+1));


	for(int i = 0; i  < len; i++){
		scanf("%d", pArr+i);
	}
	// 读取元素,和上面的for循环代码一样 
//	for(int i = 0; i  < len; i++){
//		scanf("%d", &pArr[i]);
//	}
	
	for(int i = 0; i  < len; i++){
		printf("%d ", *(pArr+i));
	}
	
	free(pArr);		// 释放动态分配的内存 
	
	return 0;
}

        realloc函数的简单使用

        前面介绍静态数组不能改变长度,而动态数组可以调整数组的长度,当需要更多的空间时可以进行扩充,当数组长度过长时可以进行减小。在C语言中通过realloc函数实实现对重新调整动态分配内存的大小。它的原型如下:

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

// 第一个参数为指向原内存块的指针,第二个重新调整的大小size

        需要注意的是,realloc函数会尽可能地在原内存块上直接进行扩展或缩小,如果原内存块的大小不够,无法直接进行扩展,那么realloc会自动寻找一个新的内存块来满足需求。如果返回的指针与原指针不同,说明内存块的位置发生了改变。在使用realloc重新分配内存后,不要忘记释放原内存块,以避免内存泄漏。

        以下是简单的代码实例:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int* nums = (int*)malloc(5 * sizeof(int));  // 分配一个初始大小的内存块
    if (nums == NULL) {
        printf("内存分配失败\n");
        return 1;
    }

    // 使用分配的内存块

    // 假设我们需要将内存块扩展到10个整数大小
    int* resized_nums = (int*)realloc(nums, 10 * sizeof(int));
    if (resized_nums == NULL) {
        printf("内存重新分配失败\n");
        free(nums);  // 释放原内存块
        return 1;
    }

    // 使用重新分配的内存块

    free(resized_nums);  // 释放重新分配的内存块

    return 0;
}

静态内存和动态内存的比较     

静态内存   
  •  静态内存由系统分配,由系统释放
  •  静态内存由栈分配 
动态内存
  • 动态内存是由程序员手动分配,手动释放
  • 动态内存是在堆分配的

跨函数使用内存的问题

静态函数不能跨函数使用,下面是一个案例,程序虽然没有报错,但是不能这么使用。

#include <stdio.h>


void f(int ** q){	// q也是一个指针变量,无论q是什么类型的指针变量,都只占有4个字节 
	int i = 5;
	// *p等价于p  
//	*p = i; 	// error 因为 *q = i等价于 p = i; 
	*q = &i; 	// 让p指向i 
}

int main(){
	
	int * p;  // p是一个指针变量 
	
	f(&p);	
	printf("%d", *p);	// 本语句没有错误,但是逻辑上有问题
						/* f终止后,其内的所有内存都会被释放,不能跨函数使用
						   这里没有编译器没有报错,这也是指针的难点。 
						*/ 
						 
	return 0;
} 

动态内存分配可以实现跨函数使用

#include <stdio.h>
#include <malloc.h> 


void f(int ** q){

	*q = (int *)malloc(sizeof(int));	// 等价于 p = (int *)malloc(sizeof(int)); 
	// 上面一行当函数运行结束后内存没有被释放 
	**q = 5;
	
}

int main(){
	
	int * p;  // p是一个指针变量 
	
	f(&p);	
	printf("%d", *p);	
	return 0;
} 

数组的定义(数据结构中)

数组的静态分配

typedef struct{
        ElemType data[Maxsize];

        int length;
}SqList;    //顺序表类型

数组的动态分配

typedef struct{
        ElemType *data;

        int length;
}SqList;    //顺序表类型

Sqlist L;

L.data = (ElemType *)malloc(sizeof (ElemType) * MaxSize);

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在C语言中,向系统动态申请存储空间通常使用malloc函数。malloc函数返回值为void*类型的指针,如果指针为NULL则说明分配失败,否则分配成功。下面是一个示例: ```c #include <stdio.h> #include <stdlib.h> int main() { int *p; p = (int *) malloc(sizeof(int)); if (p == NULL) { printf("动态内存分配失败\n"); } else { printf("动态内存分配成功\n"); free(p); // 释放动态内存 } return 0; } ``` 在上述示例中,我们通过malloc函数向系统申请了一个int类型的存储空间,并将指针p指向该空间。然后通过判断p是否为NULL来判断是否分配成功。最后需要记得在程序结束前通过free函数释放动态内存。 ### 回答2: 要判断向系统动态申请存储空间是否成功,可以使用C语言中的动态内存分配函数——malloc。 首先,使用malloc函数申请所需的存储空间,并将返回值赋给一个指针变量ptr,表示已成功申请到存储空间。 接下来,判断ptr是否为NULL。若为NULL,则说明系统动态申请存储空间失败;若不为NULL,则说明系统动态申请存储空间成功。 以下是一个示例代码: #include <stdio.h> #include <stdlib.h> int main() { int* ptr; int n; printf("请输入需申请的存储空间大小(以int为单位):"); scanf("%d", &n); ptr = (int*)malloc(n * sizeof(int)); if (ptr == NULL) { printf("系统动态申请存储空间失败\n"); } else { printf("系统动态申请存储空间成功\n"); free(ptr); // 释放申请的存储空间 } return 0; } 在以上示例中,首先通过scanf函数从用户获取需申请的存储空间大小,然后使用malloc函数动态分配了n个int类型的存储空间,并将返回的指针赋给ptr。 接着,通过判断ptr是否为NULL,输出相应的成功或失败的提示信息。 最后,在不再使用这段存储空间时,我们需要使用free函数将其释放,以防止内存泄漏。 ### 回答3: 要判断向系统动态申请存储空间是否成功,可以使用C语言中的内存分配函数malloc进行分配,然后通过判断返回的指针是否为NULL来确定分配是否成功。 下面是一个示例代码: ```c #include <stdio.h> #include <stdlib.h> int main() { int* ptr; // 定义一个指针变量 int size = 10; // 分配的存储空间大小 // 使用malloc函数动态分配存储空间 ptr = (int*)malloc(size * sizeof(int)); // 判断分配是否成功 if (ptr == NULL) { printf("分配存储空间失败!\n"); } else { printf("分配存储空间成功!\n"); // 在这里可以对分配的存储空间进行操作 // 例如,给指针赋值 for (int i = 0; i < size; i++) { ptr[i] = i; } // 释放分配的存储空间 free(ptr); } return 0; } ``` 上述代码中,我们定义了一个指针变量`ptr`,然后使用`malloc`函数动态分配了`size`个`int`类型的存储空间。接着通过判断`ptr`是否为NULL来确定分配是否成功。 如果分配成功,我们可以在代码的后续部分对分配的存储空间进行操作,例如给指针赋值、读取或修改存储空间中的数据等。最后,我们使用`free`函数释放已分配的存储空间。 注意,在使用完动态分配的存储空间后,一定要调用`free`函数来释放该空间。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值