程序,是经源码编译后的可执行文件,可执行文件可以多次被执行,比如我们可以多次打开 office。而进程,是程序加载到内存后开始执行,至执行结束,这样一段时间概念,多次打开的wps,每打开一次都是一个进程,当我们每关闭一个 office,则表示该进程结束。
有了进程和程序的概念以后,我们再来看一下,程序被加载到内存以后内存空间布局是什么样的
总体来讲说,程序源代码被编译之后主要分成两种段:程序指令和程序数据。代码区属于存放程序指令,常量区、全局数据区、堆区、栈区属于存放程序数据。程序代码区、常量区、全局数据区在程序加载到内存后就分配好了,并且在程序运行期间一直存在,大小固定,只能等到程序运行结束后由操作系统收回。栈区、堆区在程序运行时动态开辟。堆需要手动释放
int ages[10240*10240]; // 程序会崩溃, 栈溢出
通过malloc申请的存储空间一定要释放, 所以malloc和free函数总是成对出现
malloc函数
free函数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
// 1.申请1块4字节的存储空间
int *p = (int *)malloc(sizeof(int));
// 2.初始化4个字节存储空间为0
memset(p, 0, sizeof(int));
// 3.释放申请的存储空间
free(p);
return 0;
}
free()到底释放了什么? free释放的是指针指向的内存!注意!释放的是内存,不是指针!这点非常非常重要!指针是一个变量,只有程序结束时才被销毁。free释放了内存空间后,原来指向这块空间的指针还是存在!只不过现在指针指向的内容的垃圾,是未定义的,所以说是垃圾。因此释放内存后把指针指向NULL,防止指针在后面不小心又被解引用了,导致未知的问题发生。非常重要啊这一点!
在上面我们还用到一个函数memset(指针,0,数据大小)
这个函数可以说是初始化内存的“万能函数”,通常为新申请的内存进行批量初始化工作。它是直接操作内存空间,而且通常是给数组或结构体进行批量初始化。一般的变量如char、int、float、double
等类型的变量直接*p=0
初始化即可,没有必要用 memset。如果用 memset 的话反而显得麻烦
和malloc一样,但可以初始化内存空间为0值
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
{
// 1.申请4块,4个字节的存储空间
int *p = calloc(4, sizeof(int));
printf("%d",*p);
// 3.释放申请的存储空间
free(p);
return 0;
}
基于现有空间进行扩容或者缩小,利用这一特性可以完成数组动态扩容
注意事项:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
// 1.申请4个字节存储空间
int *p = NULL;
p = realloc(p, sizeof(int)); // 此时等同于malloc
// 2.使用申请好的空间
*p = 666;
printf("*p = %i\n", *p);
// 3.释放空间
free(p);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
// 1.申请4个字节存储空间
int *p = malloc(sizeof(int));
printf("p = %p\n", p);
// 如果能在传入存储空间地址后面扩容, 返回传入存储空间地址
// 如果不能在传入存储空间地址后面扩容, 返回一个新的存储空间地址
p = realloc(p, sizeof(int) * 2);
printf("p = %p\n", p);
// 2.使用申请好的空间
*p = 666;
printf("*p = %i\n", *p);
// 3.释放空间
free(p);
return 0;
}
编程时,如果您预先知道数组的大小,那么定义数组时就比较容易。例如,一个存储人名的数组,它最多容纳 100 个字符,所以您可以定义数组,如: char name[100];
但是,如果您预先不知道需要存储的文本长度,例如您想存储有关一个主题的详细描述。在这里,我们需要定义一个指针,该指针指向未定义所需内存大小的字符,后续再根据需求来分配内存,如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *description;
/* 分配30字节的内存 */
description = (char *) malloc(30 * sizeof(char));
if (description == NULL) {
fprintf(stderr, "Error - unable to allocate required memory\n");
} else {
strcpy(description, "Zara ali a DPS student.");
}
/* 假设您想要存储更大的描述信息,那么我们将description内存大小进行动态调整为100字节大小 */
description = (char *) realloc(description, 100 * sizeof(char));
if (description == NULL) {
fprintf(stderr, "Error - unable to allocate required memory\n");
} else {
//拼接字符串
strcat(description, "She is in class 10th");
}
printf("Description: %s\n", description);
/* 使用 free() 函数释放内存 */
free(description);
return 0;
}
您可以尝试一下不重新分配额外的内存,strcat() 函数会生成一个错误,因为存储 description 时可用的内存不足。
如果想看更高级的用法可以看我博客里这篇文章C语言-数据结构-单向链表
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://huanmin.blog.csdn.net/article/details/126346355
内容来源于网络,如有侵权,请联系作者删除!