C++面试题(一)

来源:互联网 发布:视频监控客户端软件 编辑:程序博客网 时间:2024/04/29 22:45

内存管理 
内存的分配方式 
答:分配方式有三种, 
1、 静态存储区,是在程序编译时就已经分配好的,在整个运行期间都存在,如全局变量、常量。 
2、 栈上分配,函数内的局部变量就是从这分配的,但分配的内存容易有限。 
3、 堆上分配,也称动态分配,如我们用new,malloc分配内存,用delete,free来释放的内存

new/delete 与 malloc()/free() 的区别? 
malloc() 与 free() 是C语言的标准库函数, new/delete 是C++的运算符, 他们都可以用来申请和释放内存, malloc()和free()不在编译器控制权限之内, 不能把构造函数和析构函数的任务强加给他们

内存分配的注意事项 
用new或malloc分配内存时,必须要对此指针赋初值。 
用delete 或free释放内存后,必须要将指针指向NULL

关于malloc/free 和new /delete 
malloc/free 是C/C+的内存分配符,new /delete是C++的内存分配符。 
注意:malloc/free是库函数,new/delete是运算符 
malloc/free不能执行构造函数与析构函数,而new/delete可以 
new/delete不能在C上运行,所以malloc/free不能被淘汰 
两者都必须要成对使用 
C++中可以使用_set_new_hander函数来定义内存分配异常的处理

delete与 delete []区别 
delete只会调用一次析构函数,而delete[]会调用每一个成员的析构函数。在More Effective C++中有更为详细的解释:“当delete操作符用于数组时,它为每个数组元素调用析构函数,然后调用operator delete来释放内存。”delete与new配套,delete []与new []配套 
MemTest *mTest1=new MemTest[10]; 
MemTest *mTest2=new MemTest; 
Int *pInt1=new int [10]; 
Int *pInt2=new int; 
delete[]pInt1; //-1- 
delete[]pInt2; //-2- 
delete[]mTest1;//-3- 
delete[]mTest2;//-4- 
在-4-处报错。 
这就说明:对于内建简单数据类型,delete和delete[]功能是相同的。对于自定义的复杂数据类型,delete和delete[]不能互用。delete[]删除一个数组,delete删除一个指针。简单来说,用new分配的内存用delete删除;用new[]分配的内存用delete[]删除。delete[]会调用数组元素的析构函数。内部数据类型没有析构函数,所以问题不大。如果你在用delete时没用括号,delete就会认为指向的是单个对象,否则,它就会认为指向的是一个数组。

new,delete和malloc,free的用法

MemTest *mTest1=new MemTest[10];MemTest *mTest2=new MemTest;Int *pInt1=new int [10];Int *pInt2=new int;delete[]pInt1; delete[]pInt2; 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

malloc和free

char *p = (char *) malloc( 100 ) //分配内存if ( *p == NULL )  //查看内存是否分配成功{ //进行申请内存失败处理}free( p )  // 释放内存p = NULL  //将内存置为空,防止也指针的出现
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

以下是几个对于可能出现内存泄露的问题 
1.

void test1(){ char string[10]; char* str1 = "0123456789"; strcpy( string, str1 );}  //字符串str1需要11个字节才能存放下(包括末尾的’\0’),而string只有10个字节的空间,strcpy会导致数组越界
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.

void test2(){ char string[10],str1[10]; int i; for(i=0; i<10; i++) {  str1 = 'a'; } strcpy( string, str1 );}  //如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string,str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3.

void test3(char* str1){ char string[10]; if( strlen( str1 ) <= 10 ) {  strcpy( string, str1 ); }}  //if(strlen(str1)<= 10)应改为if(strlen(str1) < 10),因为strlen的结果未统计’\0’所占用的1个字节
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4.

void GetMemory( char *p ){ p = (char *) malloc( 100 );}void Test( void ){ char *str = NULL; GetMemory( str ); strcpy( str, "hello world" ); printf( str );}  //传入中GetMemory(char *p )函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完char *str = NULL; //GetMemory( str ); //后的str仍然为NULL
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

5.

char *GetMemory( void ){ char p[] = "hello world"; return p;}void Test( void ){ char *str = NULL; str = GetMemory(); printf( str );}  //char p[] = "hello world"; //return p; 的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

6.

void GetMemory( char **p, int num ){ *p = (char *) malloc( num );}void Test( void ){ char *str = NULL; GetMemory( &str, 100 ); strcpy( str, "hello" ); printf( str );}  //GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句//*p = (char *) malloc( num );后未判断内存是否申请成功,应加上://if ( *p == NULL )//{// ...//进行申请内存失败处理//}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

7.

void Test( void ){ char *str = (char *) malloc( 100 ); strcpy( str, "hello" ); free( str ); ... //省略的其它语句} //char *str = (char *) malloc(100);后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上://str = NULL
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

8.

swap( int* p1,int* p2 ){ int *p; *p = *p1; *p1 = *p2; *p2 = *p;}//p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

总结: 
1.字符串是以“\0”结尾的,在拷贝数据的时候,不要忘了数组 
2.strcpy(s1,s2);strcpy函数的意思是:把字符串s2中的内容copy到s1中,连字符串结束标志也一起copy,当遇到”\0”作为结束符 
3 strlen是计算字符串的字节数,不算’\0’所占用的1个字节 
4 函数内部修改形参并不能真正的改变传入形参的值 
5 函数中的局部自动变量,在函数返回后,内存已经被释放 
6 申请了内存应该判断是否申请成功 
7 对于释放内存之后,应该把他置为NULL,防止也指针的出现

0 0
原创粉丝点击