`
haoningabc
  • 浏览: 1477817 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

c语言内存

    博客分类:
  • c
c 
阅读更多
1、C中内存分为五个区
:用来存放函数的形参和函数内的局部变量。由编译器分配空间,在函数执行完后由编译器自动释放。
:用来存放由动态分配函数(如malloc)分配的空间。是由程序员自己手动分配的,并且必须由程序员使用free释放。如果忘记用free释放,会导致所分配的空间一直占着不放,导致内存泄露。
全局局:用来存放全局变量和静态变量。存在于程序的整个运行期间,是由编译器分配和释放的。
文字常量区:例如char *c = “123456”;则”123456”为文字常量,存放于文字常量区。也由编译器控制分配和释放。
程序代码区:用来存放程序的二进制代码。
例子(1)

#include <stdlib.h>
#include <stdio.h>
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放在常量区 
}   
 
例子(2)
#include <stdlib.h>
#include <stdio.h>
char *f() 
{ 
    //s数组存放于栈上 
    //char s[4] = {'1','2','3','0'}; 
    char s[4] = "abcd"; 
    return s; //返回s数组的地址,但程序运行完s数组就被释放了 
} 
void main() 
{ 
    char *s; 
    s = f(); 
    printf("%s", s); //打印出来乱码。因为s所指向地址已经没有数据                                                                                                        
} 
~  

例子(3)
#include <stdlib.h>
#include <stdio.h>
char *f() 
{ 
    char* s = "abcd";                                                                                                                                                   
    return s; // abc 返回的是常量区
} 
int main() 
{ 
    char *s; 
    s = f(); 
    printf("%s", s); //abc
} 

指针和数组这里的区别★★★★★★★
2、动态分配释放内存
用malloc动态分配内存后一定要判断一下分配是否成功,判断指针的值是否为NULL。
内存分配成功后要对内存单元进行初始化。
内存分配成功且初始化后使用时别越界了。
内存使用完后要用free(p)释放,注意,释放后,p的值是不会变的,仍然是一个地址值,仍然指向那块内存区,只是这块内存区的值变成垃圾了。为了防止后面继续使用这块内存,应在free(p)后,立即p=NULL,这样后面如果要使用,判断p是否为NULL时就会判断出来。
例子1

#include <stdlib.h>
#include <stdio.h>
void GetMemory(char *p)
{
    p = (char *)malloc(100);
}
int main(void)
{
    char *str = NULL;
    GetMemory(str);
    strcpy(str,"hello world");
    printf(str);
}


程序首先申请一个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步,将不难发现问题所在!
#include <stdlib.h>
#include <stdio.h>
char *GetMemory(void)
{
    char p[] = "hello world";
    return p;
}
int main(void)
{
    char *str = NULL;
    str = GetMemory();
    printf(str);
}

程序首先申请一个char类型的指针str,并把str指向NULL.调用函数的过程中做了如下动作:1申请一数组p[]并将其赋值为hello world(数组的空间大小为12),2返回数组名p付给str指针(即返回了数组的首地址).那么这样就可以打印出字符串"hello world"了么?当然是不能的!因为在函数调用的时候漏掉了最后一步.也就是在第2步return数组名后,函数调用还要进行一步操作,也就是释放内存空间.当一个函数被调用结束后它会释放掉它里面所有的变量所占用的空间.所以数组空间被释放掉了,也就是说str所指向的内容将不确定是什么东西
#include <stdlib.h>
#include <stdio.h>
void GetMemory2(char **p, int num)
{
    *p = (char *)malloc(num);
}
int main(void)
{
    char *str = NULL;
    GetMemory2(&str,100);
    strcpy(str,"hello");
    printf(str);
}

正确答案为可以打印出hello.但内存泄漏了!
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
    char *str = (char *)malloc(100);
    strcpy(str,"hello");
    free(str);
    if(str != NULL)
    { 
        strcpy(str,"world");
        printf(str);
    }
}

申请空间,拷贝字符串,释放空间.前三步操作都没有任何问题.到if语句里的判断条件开始出错了,因为一个指针被释放之后其内容并不是NULL,而是一个不确定的值.所以if语句永远都不能被执行.这也是著名的"野"指针问题.所以我们在编写程序释放一个指针之后一定要人为的将指针付成NULL.这样就会避免出现"野"指针的出现.有人说"野"指针很可怕,会带来意想不到的错误.




参考http://blog.csdn.net/pfgmylove/article/details/3212163
有修正
分享到:
评论

相关推荐

    C语言内存精讲,让你彻底明白C语言的运行机制!

    4. C语言内存对齐,提高寻址效率 5. 内存分页机制,完成虚拟地址的映射 6. 分页机制究竟是如何实现的? 7. MMU部件以及对内存权限的控制 8. Linux下C语言程序的内存布局(内存模型) 9. Windows下C语言程序的内存...

    C语言内存精讲.rar

    本资源“C语言内存精讲.rar”包含了深入讲解C语言内存管理的资料,这对于想要深入学习C语言的程序员来说是一份宝贵的参考资料。 C语言的内存主要分为三个区域:栈(Stack)、堆(Heap)和静态存储区(Static Memory...

    (麻省理工免费课程)C语言内存管理和C++面向对象编程

    ### 麻省理工免费课程:C语言内存管理和C++面向对象编程 #### 一、C语言简介 在《麻省理工免费课程:C语言内存管理和C++面向对象编程》这一课程中,首先对C语言进行了介绍。C语言是一种历史悠久且功能强大的编程语言...

    C语言内存管理

    C语言内存管理是一个程序员必须掌握的重要知识点,因为它直接关系到程序运行的稳定性和效率。内存泄漏是C语言中一个非常典型的问题,指的是程序中分配的堆内存无法再被访问或回收,最终导致可用内存不断减少。内存...

    C语言内存模型总结

    对c语言内存模型和粗浅认识和总结,我们对一门学问的认识都有一个从散落到集中过程,权当一次小小的总结吧。

    推荐4款linux下的c语言内存泄漏检测工具.zip

    推荐4款linux下的检测c语言编写的程序的内存泄漏工具 C语言和其他语言相比最大的特色就是能够操作内存 但是最常犯的错误也是内存泄漏(管杀不管埋) 所以我们需要用一些工具来帮助我们检测是否存在内存泄漏,存在多少 ...

    存储引擎(C语言版本)_C语言内存管理_C语言内核编程_c语言数据结构_C语言存储引擎_

    首先,我们要理解C语言内存管理。在C语言中,程序员需要手动分配和释放内存,使用`malloc()`和`free()`函数来动态地申请和释放内存块。这样的方式虽然需要更多的编程技巧,但也提供了更高的灵活性和对内存使用的精确...

    C语言内存安全性运行时验证技术综述.pdf

    "C语言内存安全性运行时验证技术综述" C语言作为一种广泛应用于嵌入式软件和系统软件的开发语言,提供了更直接的底层内存控制,但却缺少对内存访问安全性的检测,导致C程序运行时可能产生内存安全性错误。在当前的...

    C语言内存管理资料

    有关C语言内存管理方面的培训资料,有兴趣的可以看下!

    c语言内存论文数篇(CNKI)

    这些论文集合可能是对C语言内存管理深入研究的成果,对于学习者来说是宝贵的参考资料。以下是对C语言内存管理的一些核心知识点的详细阐述: 1. **内存区域划分**: - **栈区**:由编译器自动分配释放,用于存储...

    收集一些C语言内存相关的项目.zip

    这个压缩包“收集一些C语言内存相关的项目.zip”可能包含了一系列的示例项目,旨在帮助开发者深入理解C语言中的内存操作。虽然没有具体的标签提供额外信息,但我们可以从标题和描述推测其主要内容可能包括动态内存...

    C语言内存操作的21份资料.

    本文将深入探讨这些资料所涵盖的C语言内存管理知识点。 首先,了解内存的基本概念至关重要。计算机内存分为栈(Stack)和堆(Heap)两大部分。栈主要存放函数调用时的局部变量和函数参数,而堆则是程序员动态分配和...

    有关c语言内存的思考

    "c语言内存管理和内存分配" 在C语言中,内存管理和内存分配是非常重要的知识点。本文将通过一些思考题,来帮助读者更好地理解C语言中的内存管理和内存分配。 首先,让我们来看第一个问题。在这个问题中,我们定义...

    C语言内存管理:深入剖析内存泄漏及其防治策略

    ### C语言内存管理:深入剖析内存泄漏及其防治策略 #### C语言概述 C语言作为一种通用且高效的编程语言,自20世纪70年代由丹尼斯·里奇在贝尔实验室开发以来,便因其强大的特性和广泛的适用性而在软件开发领域占据...

    【C语言/知识点整理/期末复习】C语言内存函数(附思维导图)

    C语言内存函数详解 在C语言中,内存函数是一组重要的函数,用于操作内存中的数据。这些函数包括memcpy、memmove、memset和memcmp等,都是C语言中最基本的内存操作函数。本文将对这些函数进行详细的介绍和分析。 一...

    C语言内存使用详解.pdf

    C语言内存使用详解.pdf C语言内存使用详解.pdf C语言内存使用详解.pdf

    C语言内存管理详解---c语言雷区

    C语言内存管理是程序员必须掌握的重要技能,尤其是在使用C语言编程时,因为C语言提供了直接操控内存的机制。内存管理包括了内存的分配、使用和释放,如果不谨慎处理,可能会导致各种问题,如内存泄漏、访问越界、空...

    C语言内存讲解.doc

    C语言内存讲解.doc

    嵌入式c语言内存.txt

    嵌入式c语言内存.txt

Global site tag (gtag.js) - Google Analytics