1、C中内存分为四个区
栈:用来存放函数的形参和函数内的局部变量。由编译器分配空间,在函数执行完后由编译器自动释放。
堆:用来存放由动态分配函数(如malloc)分配的空间。是由程序员自己手动分配的,并且必须由程序员使用free释放。如果忘记用free释放,会导致所分配的空间一直占着不放,导致内存泄露。
全局局:用来存放全局变量和静态变量。存在于程序的整个运行期间,是由编译器分配和释放的。
文字常量区:例如char *c = “123456”;则”123456”为文字常量,存放于文字常量区。也由编译器控制分配和释放。
程序代码区:用来存放程序的二进制代码。
例子(一)
int a = 0; //全局区
void main()
{
int b; //栈
char s[] = abc; //s在栈,abc在文字常量区
char *p1,*p2; //栈
char *p3 = 123456; //123456在常量区,p3在栈上
static int c =0; //全局区
p1 = (char *)malloc(10); //p1在栈,分配的10字节在堆
p2 = (char *)malloc(20); //p2在栈,分配的20字节在堆
strcpy(p1, 123456); //123456放在常量区
}
例子(二)
//返回char型指针
char *f()
{
//s数组存放于栈上
char s[4] = {'1','2','3','0'};
return s; //返回s数组的地址,但程序运行完s数组就被释放了
}
void main()
{
char *s;
s = f();
printf (%s, s); //打印出来乱码。因为s所指向地址已经没有数据
}
2、动态分配释放内存
用malloc动态分配内存后一定要判断一下分配是否成功,判断指针的值是否为NULL。
内存分配成功后要对内存单元进行初始化。
内存分配成功且初始化后使用时别越界了。
内存使用完后要用free(p)释放,注意,释放后,p的值是不会变的,仍然是一个地址值,仍然指向那块内存区,只是这块内存区的值变成垃圾了。为了防止后面继续使用这块内存,应在free(p)后,立即p=NULL,这样后面如果要使用,判断p是否为NULL时就会判断出来。
NO.1
void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str,hello world);
printf(str);
}
请问运行Test函数后会是什么样的结果?
NO.2
char *GetMemory(void)
{
char p[] = hello world;
retrun p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
问题同NO.1
NO.3
void GetMemory2(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str,100);
strcpy(str,hello);
printf(str);
}
问题同NO.1
NO.4
void Test(void)
{
char *str = (char *)malloc(100);
strcpy(str,hello);
free(str);
if(str != NULL)
{
strcpy(str,world);
printf(str);
}
}
问题同NO.1
我对以上问题的分析:
NO.1:程序首先申请一个char类型的指针str,并把str指向NULL(即str里存的是NULL的地址,*str为NULL中的值为0),调用函数的过程中做了如下动作:1申请一个char 类型的指针p,2把str的内容copy到了p里(这是参数传递过程中系统所做的),3为p指针申请了100个空间,4返回Test函数.最后程序把字符串hello world拷贝到str指向的内存空间里.到这里错误出现了!str的空间始终为NULL而并没有实际的空间.深刻理解函数调用的第2步,将不难发现问题所在!(建议:画图理解)
NO.2:程序首先申请一个char类型的指针str,并把str指向NULL.调用函数的过程中做了如下动作:1申请一数组p[]并将其赋值为hello world(数组的空间大小为12),2返回数组名p付给str指针(即返回了数组的首地址).那么这样就可以打印出字符串"hello world"了么?当然是不能的!因为在函数调用的时候漏掉了最后一步.也就是在第2步return数组名后,函数调用还要进行一步操作,也就是释放内存空间.当一个函数被调用结束后它会释放掉它里面所有的变量所占用的空间.所以数组空间被释放掉了,也就是说str所指向的内容将不确定是什么东西.
NO.3:正确答案为可以打印出hello.但内存泄漏了!
NO.4:申请空间,拷贝字符串,释放空间.前三步操作都没有任何问题.到if语句里的判断条件开始出错了,因为一个指针被释放之后其内容并不是NULL,而是一个不确定的值.所以if语句永远都不能被执行.这也是著名的"野"指针问题.所以我们在编写程序释放一个指针之后一定要人为的将指针付成NULL.这样就会避免出现"野"指针的出现.有人说"野"指针很可怕,会带来意想不到的错误.
分享到:
相关推荐
### C语言内存分配详解 #### 一、C语言的4G虚拟寻址空间概念 在C语言中,每个进程都有一个4GB的虚拟地址空间。这个空间被划分为不同的区域来存储不同类型的变量和数据。这里提到的4G指的是4GB(即4 * 1024 * 1024 ...
C语言内存分配问题详解 在C语言中,内存分配是一个非常重要的概念。正确地分配和释放内存对于程序的正确性和性能至关重要。本文将详细介绍C语言中的内存分配问题,包括内存的四个区、动态分配和释放内存、避免内存...
在C语言中,内存管理是程序员必须关注的重要部分。它涉及到如何为程序的变量和数据结构分配内存,...通过学习和实践这些C语言内存分配的代码,你可以更好地理解和控制程序对内存的使用,从而编写出更健壮、高效的程序。
在C语言中,动态内存分配是一项重要的编程技巧,它允许程序员在程序运行时根据需要分配内存,而不是在编译时预设固定的内存空间。本文将深入解析动态内存分配的细节和一个简单的C语言程序示例。 C语言提供了四个与...
全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。 常量存储区,这是一块比较特殊的...
以下是关于C语言内存分配的一些关键知识点: 1. **内存分配的基本概念** - **内存分配**:在C语言中,内存分为四个主要区域:代码区、数据区、BSS区(未初始化数据区)和堆区。此外,还有一个栈区,用于函数调用时...
它提供了直接访问内存的机制,如`malloc`、`calloc`、`realloc`和`free`等函数,这些函数在C语言中用于动态内存分配和释放。 内存分配主要包括两种类型:静态内存分配和动态内存分配。静态内存分配在编译时完成,...
以下是关于C语言内存分配的一些关键知识点: 1. **内存分配的基本概念** - **内存分配**:在C语言中,内存分为四个主要区域:代码区、数据区、BSS区(未初始化数据区)和堆区。程序员可以通过不同的函数来动态地...
本资源“C语言内存精讲.rar”包含了深入讲解C语言内存管理的资料,这对于想要深入学习C语言的程序员来说是一份宝贵的参考资料。 C语言的内存主要分为三个区域:栈(Stack)、堆(Heap)和静态存储区(Static Memory...
在C语言中,我们可以利用结构体、指针和动态内存分配等特性来模拟这些抽象概念。 1. 结构体:在C语言中,结构体可以用来封装资源的属性,例如资源的类型、数量、当前状态等。通过定义一个资源结构体,我们可以方便...
在C语言中,内存分配是程序管理资源的关键部分。它涉及到如何在运行时为变量和对象分配内存,以及何时和如何释放这些内存。本篇文章将深入探讨C语言的内存分配,特别是动态内存分配,以及与之相关的堆内存分配。 ...
### C语言内存管理知识点 #### 一、C语言内存管理概览 在C语言中,内存管理是一项核心技能,尤其对于高效程序设计至关重要。本文档将深入探讨C语言中的内存管理机制,帮助开发者理解不同类型的内存分配以及如何...
C语言内存分配详解 C语言中内存分配是指在程序设计中对内存资源的管理。在计算机系统或嵌入式系统中,内存资源仍然是有限的,因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题。 根据C语言的内存管理...
C语言内存管理是一个程序员必须掌握的重要知识点,因为它直接关系到程序运行的稳定性和效率。内存泄漏是C语言中一个非常典型的问题,指的是程序中分配的堆内存无法再被访问或回收,最终导致可用内存不断减少。内存...
在C语言中,动态内存分配是通过malloc函数实现的。malloc函数的原型为void *malloc(size_t n),其中n是要分配的内存的大小,返回值是分配内存的块的首地址。 例如,使用malloc函数分配一个可以容纳10个整型元素的...
本实验主要是模拟在分页式管理方式下用位视图来表示内存分配情况,实现主存空间的分配和回收。用一个8*8矩阵表示内存的占用状态,1表示已经占用,0表示未占用要求输入作业名字和所需内存块。
1. **`malloc`函数**:`malloc`是C语言中用于动态内存分配的标准库函数,它返回指向已分配内存块的指针。程序员可以通过`free`函数来释放不再使用的内存,以避免内存泄漏。 2. **`new`操作符**:在C++中,`new`...
本项目专注于C语言中的动态内存分配,这在处理数据结构如链表、树或大型数组等时特别有用。在“动态内存分配C语言实现”中,我们将探讨以下几个关键知识点: 1. **malloc() 函数**:这是C语言中用于动态分配内存的...