博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C/C++题目--内存管理
阅读量:2382 次
发布时间:2019-05-10

本文共 4255 字,大约阅读时间需要 14 分钟。

填空题:

(1)从变量的定义位置分,可分为全局变量局部变量。其中,局部变量定义在函数或复合语句中,供函数或复合语句中使用。

(2)变量的存储类型分为auto,extern,register, static。当声明一个静态(static变量,它既具有局部变量的性质,又具有全局变量的性质。

(3)C++程序的内存分为4个区:全局数据区代码区栈区堆区。全局变量,静态变量,字符串常量存放在全局数据区,所有在函数和代码存放在代码区,为运行函数而分配的函数参数,局部变量返回地址存放在栈区。动态分配的内存在堆区

(4)全局变量,静态变量具有静态生存期;局部变量生存期为动态

(5)函数原型中形参标识符的作用域为为函数原型,函数的形参与

函数体作用域为块作用域;函数,全局变量与常量有文件作用域。

( 6)C++源程序中以#开头,以换行符结尾的行称为预处理命令。预处理命令编译前由预处理器执行。

( 7)可以通过3种方法使用名字空间,个别使用声明方式全局声明方式全局声明个成员

2.

(1)在C++中,函数默认的存储类别为:auto

(2)函数的形式参数是局部变量,在一个函数体内定义的变量只在本函数范围内有效, 在函数的复合语句中定义的变量只在此复合语句中有效 。

( 3) # define PI 3.14 预处理命令必须以 #开头,凡是以 #开头的都是

预处理命令行,在程序执行前执行预处理命令。

( 4)动态分配的内存要用 delete释放,局部 auto变量分配的内存在

函数调用结束时释放,全局变量的内存在程序结束时释放。

memset问题

memset初始化函数:将某一块内存中的内容全部设置为指定的值,即做初始化工作

memset原型:

题目:请解释以下该函数以及其参数的含义:void *memset(void *s,int ch,size_t n);?

【答案】

作初始化函数,将某一块内存中的内容全部设置为指定的值。

参数:s是需要初始化的变量,ch是替换s首n个字节的值,n是n个字节。

题目:以下代码是否正确?

char *s=”Golden Global View”;

memset(s,’G’,6);

答案

是错误的。因为s已指向一个常量字符串。所以无法用memset函数来对此s进行修改值。

题目:

char buffer[20];

memcpy(buffer,”123”,3)

是否正确?

答案

错误。因为buffer没有被初始化,也就是没有值,如果直接使用memcpy函数的话,就会打印出后面的值是乱码的。

应该修改为:

char buffer[20];

memset(buffer,0,sizeof(char)*20);

memcpy(buffer,”123”,3);

题目:memset函数对哪些类型不能初始值为1?

答案

char data[10];memset(data,0,sizeof(data));//0memset(data,-1,sizeof(data));//-1memset(data,1,sizeof(data));//1

        一般memset设置值的范围为0—255.这是因为后八位才是有效的值,后八位的前面位数无论设置多少的值,一律都按后八位的值来计算。比如说:0100 0000 0110 0001,就算设置了这个值,处理结果仍然按照后八位0110 0001来输出。如果data是char类型,输出结果范围为-128到127。

那么在int ,float,double类型方面就不同了,结果有效值只为0或-1,不能设置为1,否则,输出结果就会是随机数。

如果是bool类型,则结果有效值为0到255。

如果是其他对象:

structdata data;memset(&data,0,sizeof(structdata));

题目:

struct Data{int *p;};Data data;data.p=new int[10];memset(data,0,sizeof(data));

是否正确?

答案

不正确。虽然编译通过,但是当解引用结构体内的p指向的内容会使程序崩溃。因为memset函数只是初始化该结构体,但是对p指向的堆内存并没有进行初始化,并且调用该函数时,p将会设置值为0,即空指针。这也会造成内存泄漏的问题,导致无法获知地址并无法释放掉此堆内存。

malloc问题

题目:在调用malloc()的时候,错误“不能把void*转换为int*”是什么意思?

答案

说明你用的是C++编译器而不是C编译器。

题目:我有个程序分配了大量的内存,然后又释放了。但是从操作系统看,内存的占用率却并没有变回去

答案

多数malloc/free的实现并不把释放的内存返回操作系统,而是留着供同一程序的后续malloc()使用。

题目:free()怎么知道有多少字节需要释放?

答案

malloc/free的实现会在分配的时候记下每一块的大小,所以在释放的时候就不必再考虑它的的大小了。(通常,这个大小就记录在分配的内存块旁边,因此,对超出分配内存块边界的内存哪怕是轻微的改写,也会导致严重的后果。)

题目:为什么sizeof不能告诉我它所指的内存块的大小?

答案

sizeof操作符并不知道你使用了malloc为指针分配内存,sizeof只能得到指针本身的大小。没有什么可移植的办法得到malloc分配的内存块的大小。

题目(7.35)calloc()malloc()有什么区别?应该用哪一个?利用calloc的零填充功能安全吗?free()可以释放calloc()分配的内存吗,还是需要一个cfree()

答案

calloc(m,n)本质上等价于

p=malloc(m*n);

memset(p,,m*n);

除了参数个数不同和用零填充之外,这两个函数并无其他重要的区别。

题目:什么情况下会发生段错误?

【答案】

段错误通常发生在访问非法内存地址的时候,比如使用野指针,或者试图修改字符串常量的内容

题目:newmalloc的区别?

【答案】(答案摘自某博文)

1、new分配内存按照数据类型进行分配,malloc分配内存按照指定的大小分配;

2、new返回的是指定对象的指针,而malloc返回的是void*,因此malloc的返回值一般都需要进行类型转化。

3、new不仅分配一段内存,而且会调用构造函数malloc不会

4、new分配的内存要用delete销毁,malloc要用free来销毁;delete销毁的时候会调用对象的析构函数,而free则不会。

5、new是一个操作符可以重载,malloc是一个库函数

6、malloc分配的内存不够的时候,可以用realloc扩容。扩容的原理?new没用这样操作。

7、new如果分配失败了会抛出bad_malloc的异常,而malloc失败了会返回NULL

8、申请数组时: new[]一次分配所有内存,多次调用构造函数,搭配使用delete[],delete[]多次调用析构函数,销毁数组中的每个对象。而malloc则只能sizeof(int) * n

题目:A* a = new A; a->i = 10;在内核中的内存分配上发生了什么?(题目不严谨,应是在函数内定义A *a

【答案】

1)A *a:a是一个局部变量,类型为指针,故而操作系统在程序栈区开辟4/8(在32位机器下,为4个字节)字节的空间(0x000m),分配给指针a

2)new A:通过new动态的在堆区申请类A大小的空间(0x000n)。

3)a = new A:将指针a的内存区域填入栈中类A申请到的地址的地址。即*(0x000m)=0x000n。

4)a->i:先找到指针a的地址0x000m,通过a的值0x000n和i在类a中偏移offset,得到a->i的地址0x000n + offset,进行*(0x000n + offset) = 10的赋值操作,即内存0x000n + offset的值是10。

题目:对于虚函数,说说类的内存分布?

【答案】

virtual修饰符

如果一个类是局部变量则该类数据存储在栈区,如果一个类是通过new/malloc动态申请的,则该类数据存储在堆区。

如果该类是virutal继承而来的子类,则该类的虚函数表指针和该类其他成员一起存储。虚函数表指针指向只读数据段中的类虚函数表,虚函数表中存放着一个个函数指针,函数指针指向代码段中的具体函数。

如果类中成员是virtual属性,会隐藏父类对应的属性。

题目:静态变量何时分配内存并初始化?

【答案】

静态变量中的数据段和BSS段,在执行代码之前初始化,也属于编译器初始化。但对于静态对象来说,当对象首次创建,则就会对这些对象进行构造并初始化,直至程序退出才会销毁内存。

题目:栈溢出一般是由什么原因导致的?

【答案】

没有回收垃圾资源。

题目:全局变量可不可以定义在可被多个.C 文件包含的头文件中?为什么?

【答案】

可以,在不同的C 文件中以static形式来声明同名全局变量。可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错。

题目:如何引用一个已经定义过的全局变量?

【答案】

可以用引用头文件的方式,也可以用extern 关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变量写错了,那么在编译期间会报错,如果你用extern 方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。

题目:A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?这两个static变量会保存到哪里(栈还是堆或者其他的)?

【答案】

static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。

他们都放在静态数据区,但是编译器对他们的命名是不同的。如果要使变量在其他模块也有意义的话,需要使用extern 关键字。

该函数被C 编译器编译后在库中的名字为_foo,而C++ 编译器则会产生像_foo_int_int之类的名字。 C++提供了C 连接交换指定符号extern“C”来解决名字匹配问题。

 

转载地址:http://cwwab.baihongyu.com/

你可能感兴趣的文章
在linux内核中操作文件的方法
查看>>
Linux下Socket编程
查看>>
Linux内核和用户空间通信的方式— proc文件和mmap共享内存
查看>>
基于DSP/BIOS和NDK的嵌入式网络操作系统设计方案
查看>>
CCS开发环境搭建小结
查看>>
DM642 gel文件和.cmd文件参考
查看>>
DSP软件优化小实验
查看>>
DSP/BIOS 介绍
查看>>
多线程编程之重点--使用DSP/BIOS时选择线程类型的参考方法
查看>>
DSP/BIOS在嵌入式数据采集系统中的应用
查看>>
基于DSP/BIOS和NDK的嵌入式网络操作系统设计方案
查看>>
迅雷C++试题及解答
查看>>
Linux 中断学习之小试牛刀篇
查看>>
中断之原理篇
查看>>
高内聚 低耦合
查看>>
GUI开发之DirectFB
查看>>
GTK/DirectFB两个闪烁的问题
查看>>
《Linux内核修炼之道》 之 高效学习Linux驱动开发
查看>>
编写可移植C/C++程序的要点
查看>>
DirectFB代码导读
查看>>