精华内容
下载资源
问答
  • 内存中如何存放数据

    千次阅读 2019-01-03 09:16:53
    · 计算机执行程序时,组成程序的指令和程序所操作的数据都必须存放在某个地方 · 这个地方就是计算机的内存(也称为主存或随机访问存储器),类比人类的大脑,内存就是程序员的一切,非常重要   注意:主存和...

    1、计算机使用内存来记忆或存储计算时使用的数据

     

    · 计算机执行程序时,组成程序的指令和程序所操作的数据都必须存放在某个地方

    · 这个地方就是计算机的内存(也称为主存或随机访问存储器),类比人类的大脑,内存就是程序员的一切,非常重要

     

    注意:主存和RAM的区别

     

    2、组成计算机内存的单位是bit(位)。binary digit(二进制数字)

     

    8 bit(比特) = 1 byte (字节)

    10M带宽:10M bps( bit per second )

    内存分配方式 

    内存分配方式有三种: 

    (1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。 

    (2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 

    (3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。 

     

    常见的内存错误及其对策 

    发生内存错误是件非常麻烦的事情。编译器不能自动发现这些错误,通常是在程序运行时才能捕捉到。而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。有时用户怒气冲冲地把你找来,程序却没有发生任何问题,你一走,错误又发作了。 

    常见的内存错误及其对策如下: 

    • 内存分配未成功,却使用了它。 

    编程新手常犯这种错误,因为他们没有意识到内存分配会不成功。常用解决办法是,在使用内存之前检查指针是否为NULL。如果指针p是函数的参数,那么在函数的入口处用assert(p!=NULL)进行检查。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。

    • 内存分配虽然成功,但是尚未初始化就引用它。 

    犯这种错误主要有两个起因:一是没有初始化的观念;二是误以为内存的缺省初值全为零,导致引用初值错误(例如数组)。 

    内存的缺省初值究竟是什么并没有统一的标准,尽管有些时候为零值,我们宁可信其无不可信其有。所以无论用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略,不要嫌麻烦。

    • 内存分配成功并且已经初始化,但操作越过了内存的边界。 

    例如在使用数组时经常发生下标“多1”或者“少1”的操作。特别是在for循环语句中,循环次数很容易搞错,导致数组操作越界。

    • 忘记了释放内存,造成内存泄露。 

    含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足,你看不到错误。终有一次程序突然死掉,系统出现提示:内存耗尽。 

    动态内存的申请与释放必须配对,程序中malloc与free的使用次数一定要相同,否则肯定有错误(new/delete同理)。

    • 释放了内存却继续使用它。 

    有三种情况: 

    (1)程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。 

    (2)函数的return语句写错了,注意不要返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。(return ?) 

    (3)使用free或delete释放了内存后,没有将指针设置为NULL。导致产生“野指针”。

    【规则1】用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。 

    【规则2】不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。 

    【规则3】避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。 

    【规则4】动态内存的申请与释放必须配对,防止内存泄漏。 

    【规则5】用free或delete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。 

     

    · 动态内存会被自动释放吗? 

    函数体内的局部变量在函数结束时自动消亡。很多人误以为示例是正确的。理由是p是局部的指针变量,它消亡的时候会让它所指的动态内存一起完蛋。这是错觉!

    void Func(void)
    
    { 
    
    char p = (char ) malloc(100);
    
    // 动态内存会自动释放吗? 
    
    } 

    我们发现指针有一些“似是而非”的特征:

     

    (1)指针消亡了,并不表示它所指的内存会被自动释放。 

    (2)内存被释放了,并不表示指针会消亡或者成了NULL指针。 

    这表明释放内存并不是一件可以草率对待的事。也许有人不服气,一定要找出可以草率行事的理由: 

    如果程序终止了运行,一切指针都会消亡,动态内存会被操作系统回收。既然如此,在程序临终前,就可以不必释放内存、不必将指针设置为NULL了。终于可以偷懒而不会发生错误了吧? 想得美。如果别人把那段程序取出来用到其它地方怎么办? 

     

    ·  内存耗尽怎么办? 

    如果在申请动态内存时找不到足够大的内存块,malloc和new将返回NULL指针,宣告内存申请失败。通常有三种方式处理“内存耗尽”问题。 

    (1)判断指针是否为NULL,如果是则马上用return语句终止本函数。例如: 

    void Func(void) 
    
    { 
            A *a = new A; 
    
            if(a == NULL) 
    
            { 
    
                    return; 
    
            } 
    
    … 
    
    }

    (2)判断指针是否为NULL,如果是则马上用exit(1)终止整个程序的运行。例如: 

    void Func(void) 
    
    { 
    
            A *a = new A; 
    
            if(a == NULL) 
    
            { 
    
            cout << “Memory Exhausted” << endl; 
    
            exit(1); 
    
            } 
    
    … 
    
    }

    (3)为new和malloc设置异常处理函数。例如Visual C++可以用_set_new_hander函数为new设置用户自己定义的异常处理函数,也可以让malloc享用与new相同的异常处理函数。

    上述(1)(2)方式使用最普遍。如果一个函数内有多处需要申请动态内存,那么方式(1)就显得力不从心(释放内存很麻烦),应该用方式(2)来处理。 很多人不忍心用exit(1),问:“不编写出错处理程序,让操作系统自己解决行不行?” 

    不行。如果发生“内存耗尽”这样的事情,一般说来应用程序已经无药可救。如果不用exit(1) 把坏程序杀死,它可能会害死操作系统。道理如同:如果不把歹徒击毙,歹徒在老死之前会犯下更多的罪。

    有一个很重要的现象要告诉大家。对于32位以上的应用程序而言,无论怎样使用malloc与new,几乎不可能导致“内存耗尽”。我在Windows 98下用Visual C++编写了测试程序,见示例。这个程序会无休止地运行下去,根本不会终止。因为32位操作系统支持“虚存”,内存用完了,自动用硬盘空间顶替。我只听到硬盘嘎吱嘎吱地响,Window 98已经累得对键盘、鼠标毫无反应。 我可以得出这么一个结论:对于32位以上的应用程序,“内存耗尽”错误处理程序毫无用处。这下可把Unix和Windows程序员们乐坏了:反正错误处理程序不起作用,我就不写了,省了很多麻烦。 必须强调:不加错误处理将导致程序的质量很差,千万不可因小失大。

    void main(void) 
    
    { 
    
            float *p = NULL; 
    
            while(TRUE) 
    
            { 
    
            p = new float[1000000]; 
    
            cout << “eat memory” << endl; 
    
            if(p==NULL) 
    
                   exit(1); 
    
            } 
    
    } 
    
    

     

    展开全文
  • JVM内存中各部分存放的内容

    千次阅读 2018-01-18 09:53:54
    虚拟机内存中主要有程序计数器、虚拟机栈、本地方法栈、堆和方法区。 程序计数器和虚拟机栈都是线程“私有”的内存程序计数器是一块比较下的内存空间,主要村放代码执行的位置。分支、循环、跳转、异常处理...
    虚拟机内存中主要有程序计数器、虚拟机栈、本地方法栈、堆和方法区。

    程序计数器和虚拟机栈都是线程“私有”的内存。
    程序计数器是一块比较下的内存空间,主要村放代码执行的位置。分支、循环、跳转、异常处理、线程恢复等基础功能都需要一来这个计数器来完成。
    例如,多线程中,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,他们之间互不影响,独立存储。

    经常有人把java内存分为堆内存和栈内存。这里所说的栈指的就是虚拟机栈。虚拟机栈中存放了各种基本数据类型和对象引用。比如int i。这时候机会在栈中分配一个int类型的内存给i,并初始化为零值。本地方法栈和虚拟机栈所发挥的作用是非常相似的,他们之间的区别不过是虚拟机栈为虚拟机执行java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务。

    堆和方法区是各个线程共享的内存区域
    (Java Heap)是虚拟机所管理的内存中最大的一块,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存,但是随着JIT编译器的发展和逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化发生,所有的对象都分配在堆上就变得不是那么绝对了。

    方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
    运行时常量池是方法区的一部分,用于存放编译器生成的各种字面量和符号引用。
    展开全文
  • 共享内存能否存放指针的结构体?  共享内存是第二种IPC工具。他允许两个无关的进程访问相同的逻辑内存。共享内存是在两个运行的程序之间传递数据的有效手段。尽管X/Open标准并没有要求,很可能绝大数的...

    http://www.cnblogs.com/knightly/p/3525456.html

    共享内存能否存放带有指针的结构体?

      共享内存是第二种IPC工具。他允许两个无关的进程访问相同的逻辑内存。共享内存是在两个运行的程序之间传递数据的有效手段。尽管X/Open标准并没有要求,很可能绝大数的共享内存实现都是会将不同进程之间正在共享的内存安排在相同的物理内存中。

      共享内存为在多个进程之间共享与传递数据提供一个有效的手段。因为他并没有提供同步的方法,所以通常我们需要使用其他的机制来同步对共享内存的访问。通常,我们也许会使用共享内存来提供对大块内存区的有效访问,并且传递少量的消息来同步对此内存的访问。

      向共享内存存放带有指针的结构体时,当再次向共享内存取出这个指针的值时,会出现内存错误。

      结构体结构如下:  

      typedef struct base_array{
          int size ;
          int count ;
          struct base *data;
      }base_array;

      程序大致如下:

      int main(){

        shmid=shmget(key,SHARED_SEGMENT_SIZE,0666 | IPC_EXCL) ;  //创建共享内存

        if(fork()==0) {  //子进程

          shmptr=(base_array *)shmat(shmid,0,0);            //拿到共享内存的首地址

          L->size = number;                        //初始化L(base_array型)
             L->count = 0 ;
             for(i=0;i<number;i++){
                sprintf(string,"%d",i) ;
                strcpy(L->data[i].id,string) ;
                L->data[i].next = NULL ;
                L->count++ ;
             }

          memcpy(shmptr,&L,(sizeof(base)+sizeof(base_array))*(L.count));//将L的东西复制给shmptr

          sem_v(semid) ;                          //互斥

        }else{      //父进程

          shmptr=(base_array *)shmat(shmid,0,0);            //拿到共享内存的首地址

          sem_p(semid);                          //互斥

          printf("size=%d\n",shmptr->size);                //成功
                     printf("count=%d\n",shmptr->count);              //成功
                     printf("L->data[0]=%s\n",shmptr->data[0].id);          //失败

        }  

      }

      分析: size和count打印成功,而data[0].id打印失败。因为,size和count已经从子进程的内存中复制到了共享内存中了,而仅仅是把data的指针值复制到了共享内存里面,而真正的

          内容仍然在子进程的内存里面。当主进程去取这个值的时候,系统是在共享内存里面寻址,所以肯定会导致错误。

     

    展开全文
  • 实型数据在内存中存放形式

    千次阅读 2018-08-19 17:22:40
    1.实型数据在内存中存放形式 实型数据一般占4个字节(32位)内存空间。按指数形式存储。实数3.14159在内存中存放形式如下: + .314159 + 1  数符 小数部分 指...

    实型变量

    1.实型数据在内存中的存放形式

    实型数据一般占4个字节(32位)内存空间。按指数形式存储。实数3.14159在内存中的存放形式如下:

    +

    .314159

    +

    1

              数符           小数部分                        指符        指数

    小数部分占的位(bit)数愈多,数的有效数字愈多,精度愈高。

    指数部分占的位数愈多,则能表示的数值范围愈大。

    实际上,小数部分是一个二进制纯小数,指数部分以补码存放。

    2.实型变量的分类

    实型变量分为:单精度(float型)、双精度(double型)和长双精度(long double型)三类。

    在Turbo C中单精度型占4个字节(32位)内存空间,其中数符1位,小数部分23位,指符1位,指数7位,所以其数值范围为3.4E-38~3.4E+38,只能提供6~7位有效数字。双精度型占8 个字节(64位)内存空间,其中数符1位,小数部分23位,指符1位,指数10位,其数值范围为1.7E-308~1.7E+308,可提供15~16位有效数字。

    表2.2

    类型说明符

    比特数(字节数)

    有效数字

    数的范围

    Float

    32(4)

    6~7

    10-37~1038         

    Double

    64(8)

    15~16

    10-307~10308

    long double

    128(16)

    18~19

    10-4931~104932

    3.实型变量的定义形式及初始化与整型相同。

    类型说明符:float(单精度实型), double(双精度实型)。 

    例如:

    float x=1.27 , y=3.5 4;        /*x,y为单精度实型变量,且初值为:1.27和3.54*/

    double a,b,c;    /* a,b,c为双精度实型变量*/

    在计算机中,存放浮点数一般采用定点数和浮点数两种表示方法。C语言中采用的是浮点数表示法,以Turbo C中的float型的7.8125×10-2为例,其数据存储的格式如下

    0

    10100000000000000000000

    1

    0000011

    数符        小数部分(23位)                指符   指数(7位)

    即二进制的0.101×10-11,转化为十进制为0.625×2-3,即7.8125×10-2。

           对于double型的数据小数部占53位(包括数符一位),指数部分占11位(包括指符一位)。

           对于long double型的数据小数部分占113位(包括数符一位),指数部分占15位(包括指符一位)。

    4.实型数据的舍入误差

    实型变量也是由有限的存储单元组成的,能提供的有效数字是有限的。这样就会存在舍入误差。看一个例子:

    【例2.8】一个较大实数加一个较小实数。

    main()

    {

    float x=7.24356E10, y;

                y=x+54;

    printf("x=%e\n",x);

    printf("y=%e\n",y);

    }

    程序执行的结果为:

    x=7.24356E10

    y=7.24356E10

    这里x和y的值都是7.24356E10,显然是有问题的,原因是由于float只能保留6~7位有效数字,变量y所加的54被舍弃。因此由于舍入误差的原因,进行计算时,要避免一个较大实数和一个较小实数相加减。

    5.实型数据的溢出

    【例2.9】

    main()

    {

                 float a,b,c,d;

    a=1.2E33;

    b=0.5E-22;

    c=0.25E-21;

    d=a/b;

    d=d*c;

                printf("c=%f\n ",d);

          }

    结果会出现

    Floating point error: Overflow

    这是由于程序中a/b的运算的结果超出了float型能表示的范围产生溢出。所以在使用中应避免直接用一个较大的数除以一个较小的数。可以将程序的计算部分d=a/b; d=d*c; 改为:

    d=a*c; d=d/b; 或 d=a/b*c;

    以避免这种情况的发生。也许有人会提出d=a/b*c为什么不产生溢出哪?其原因是,在Turbo C中float型数据在计算时要先转换为double型数据,计算后再转换为float型数据赋给float变量d。

    2.4.3实训 使用实型数据

    实训目的:正确书写实型常量,合理选择实型变量存放数据

    实训内容

    1、已知三角形的底为2.8cm,高为4.3cm,求三角型的面积。

    编程如下:

    main()

    {float d=2.8,h=4.3, s;

    s=d*h/2;

    printf(“s=%f”,s);

    }

    程序运行的结果为:

    s=6.020000

         2、将摄氏温度27.5度转换为华氏温度。转换公式为

    编程如下:

    main()

    {

    float f=27.5,c;

    c=5.0/9*(f-32);

    printf(“c=%f”,c);

    }

    程序运行的结果为:

    c=-2.500000

    3、上机验证1.0/7*7的结果是否为1.0。为什么?

    展开全文
  • 程序内存中的布局

    千次阅读 2017-08-06 14:00:57
    1、代码段代码段(code segment)存放程序执行的机器指令。通常情况下,代码段是可共享的,使其可共享的目的是,对于频繁被执行的程序,只需要在内存中有一份副本即可。代码段是只读的,使其只读的原因是
  • 点击进入_更多_Java千百问1、String在内存中如何存放了解String是什么看这里:String是什么 String是一个特殊的包装类数据。 可以用两种的形式来创建:String str = new String( "abc" ); String str = "abc" ;...
  • 堆和栈的区别 (stack and heap)一般认为在c分为这几个存储区 1栈 - 编译器自动分配释放 2堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 3全局区(静态区),全局变量和静态变量的存储...
  • 关于数组在内存中存放

    千次阅读 2015-09-04 20:49:16
    由腾讯的一个笔试题牵涉的知识点,自己之前没有接触过,就总结了一下: ...【解析】若在内存中,则数据可以”随机存取”,但内存数据被读取或写入时,所需要的时间与这段信息所在的位置无关.但是在读
  • 程序中数据存放的位置

    千次阅读 2017-10-16 17:30:50
    基本上程序员在开始接触Linux编程时就大抵就都听过代码段、数据段等等概念,它们是各种数据存放的位置。通过objdump -h命令可以查看一个.o文件(已编译成二进制文件但未链接)的各个段: 1. 代码段(.txt)   ....
  • 循环程序设计方法 求A和B两个4字节BCD数之和 他们在内存中以压缩BCD码形式存放 ;低字节在前 高字节在后 要求结果以同样形式存放以SUM的单元 data segment a db 44h,33h,22h,11h ;数A BCD数 加上后缀H b db 88h,...
  • 一维数组在内存中存放

    千次阅读 2018-04-04 19:51:20
    1 硬盘上不可能运行程序的,必须在内存中运行。2 低地址到高地址存储 3 数组元素通常也称为下标变量。4 在C语言,只能逐个地使用下标变量, 不能用一个语句输出整个数组5 int a[10]和t=a[6]分别是定义数组长度为...
  • C语言局部变量和全局变量变量的存储类别(static,extern,auto,register) 1----局部变量和全局变量 在讨论函数的形参变量时曾经提到,形参...不仅对于形参变量,C语言所有的量都自己的作用域。变量说明的方式不同
  • 局部变量分配的内存在栈里:栈大小与编译器有关。默认情况下,visual studio 2010 的栈大小为1M。 ...动态分配的数据存在内存的堆里面:在VS2010的默认情况下,32位程序可以申请的堆大小最大是2G,
  • 进程内存布局各段存放内容

    千次阅读 2013-09-04 22:14:45
    BSS段(bsssegment)通常是指用来存放程序中未初始化的全局变量和静态变量(全局和局部)的一块内存区域。BSS是英文BlockStarted by Symbol的简称。BSS段属于静态内存分配。 data段: 数据段(datasegment)通常...
  • 内存中以BUF单元开始缓冲区连续存放着10个学生的分数,试编制程序统计其中90一100分、80一89分、60一79分及60分以下者各多少人,并把结果分别存放在S9、S8、S7和S6。 声明:本人使用Masm for Windows 2015...
  • 最近在学习C语言深度剖析,读到了关于数据在内存中存放:大端、小端模式... 关于 big-endian and little-endian ... 自编Test小程序: #include #include int main(void) {  int a[5] ...
  • 程序中各变量在内存中的位置

    千次阅读 2014-12-05 16:15:01
    主要给初学者介绍下,我们编写的程序中,我们的代码,全局变量和静态变量在内存中是怎么存放的,我们new或者malloc出来的变量,在内存中是怎么分配的, 全局变量,静态变量----存于数据区; 局部变量,函数...
  • java程序内存中的分布

    千次阅读 2016-04-11 10:44:07
    在java,java程序内存中的分布可分为三大模块:堆内存、栈内存和方法区。 堆内存:用于内存空间的申请;用于存放new创建的对象和数组,jvm会定期进行检查,如果不被引用,则回收。 栈内存 : 保存本地变量的...
  • JVM各内存区域存放内容

    千次阅读 2018-10-04 11:33:18
    一、方法区存放内容: 1.类的全限定名(类的全路径名)。 2.类的直接超类的权全限定名(如果这个类是Object,则它没有超类)。 3.类的类型(类或接口)。 4.类的访问修饰符,public,abstract,final等。 5.类...
  • 程序内存四区

    千次阅读 2018-08-09 19:38:37
    在C语言程序中: 代码在内存中进行执行的时候,我们粗略的将程序所占用的内存分为四个区域—-栈区,堆区,全局区,代码区,每个程序都唯一的四个内存区域.我们需要熟悉和了解各个区域的特性,例如存储什么类型的数据, ...
  • C程序中内存分布

    万次阅读 2019-05-30 22:00:21
    C语言,定义了5个内存区间:代码区;全局变量和静态变量区;局部变量区即栈区;动态存储区,即堆区;常量区。 1)栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。 2)堆区(heap...
  • 内存的分区与数据的存放

    千次阅读 2018-07-23 19:34:58
    典型的存储器安排(Linux下的内存分配) 栈区:由编译器自动分配与释放。用于存放局部变量、函数参数、函数返回值。特点:效率高,但空间大小有限。 堆区:使用malloc或者new开辟的空间都是在堆上分配的,需要...
  • 程序内存中的布局结构

    千次阅读 2019-04-21 14:07:07
    转自:https://my.oschina.net/pollybl1255/blog/140323,并根据自己的理解做了整理 参考: https://www.cnblogs.com/mfmdaoyou/p/6792665.html... ... BSS段:(bss segment)通常是指用来存放程序中未初始化的全局变...
  • 程序内存映像

    千次阅读 2017-12-24 16:51:42
    计算机程序在运行时,操作系统首先要将存放在外存储器(硬盘)上的可执行文件代码装载到计算机的内存中,然后运行内存中程序代码。所以要聊程序的运行情况,只要看内存中程序代码是怎么运行的就可以了。  程序...
  • 下面几种网上的理解,我整理一下:一: 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员...
  • 程序运行时的内存空间分布

    万次阅读 多人点赞 2014-03-21 01:33:18
    我们在写程序时,既程序的逻辑代码,也程序中定义的变量等数据,那么当我们的程序进行时,我们的代码和数据究竟是存放在哪里的呢?下面就来总结一下。 一、程序运行时的内存空间情况 其实在程序运行时,...
  • 计算机学科的很多问题,都是因为概念的...几经周折,结合多篇文章,对内存中数据存放次序终于了较深入的理解,现记录如下: 一、几个概念:  1.内存中关于数据的存放顺序三个层次(即三种不同的视角):  
  • linux应用程序内存布局

    千次阅读 2015-11-10 18:15:44
    1.linux应用程序内存布局 从低地址到高地址分别为:...不冲突,因为这个地址是一个虚拟地址,linux每个应用程序自己的虚拟地址空间。 2.2.查看linux应用程序内存布局方 法:通过查看应用程序进程的进程地址

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 669,778
精华内容 267,911
关键字:

内存中存放的有程序吗