最近面试,关于内存分配的题居然答错了,复习下。
一、union内存分配
在union中所有的成员公用一块内存,同一时间只能存储一个成员的值。那么其内存分配的规律是啥,看下面两个例子。
union test1{
int a;
char b;
double c;
};
union test2{
char a[9];
int b;
};
test1中最大的基本数据类型为8,即按8对齐,而占据最大空间的也是8,所以分配内存空间为8。test2中最大的基本数据类型为4,所以按4对齐,而占据最大空间的为9,按照4对齐则占据空间为12。即分配内存空间为12。从这两个例子可以看出union的内存分配规律。
二、struct内存分配
还是以三个例子来寻找规律。
struct test1{
char a;
double b;
int c;
};
struct test2{
char a;
char b;
double c;
};
struct test3{
double a;
char b;
int c;
};
test1中char a是一字节的,按一对齐,故先分配一字节;但double是八字节,按 八字节对齐,所以要在char a之后再空七个字节,再分配double b,所以就是16字节;而int c是4字节对齐的,可以从16开始分配,即现在占20个字节。但结构体最大的是double,所以整体要八字节对齐,即占24字节。
test2中char a,char b都是按照一字节对齐的,所以先分配二个字节给a,b;然后分配double c,但c占八个字节,所以要空六个字节,再分配double,即总共占16字节。
现在知道了吧,test3也为16。总结下规律吧,比union稍微复杂点:
struct分配是按照每个成员来的,即每个成员的起始地址都和变量本身的类型相关,而分配结束后占的总体空间要为最大基本变量的倍数。
三、struct 和union混合型。
以两个例子来说明。
struct inner{
char a;
double b;
char c;
};
union test1{
inner a;
int b;
char c;
};
struct test2{
inner a;
int b;
char c;
};
易知inner占24字节,那么test1最大基本类型为8,所以按8对齐,根据union特性,test1为28。
test2最大基本类型也为8,那么给inner a分配24字节后,int b再分配4字节,char分配一字节,要按8对齐即分配32字节。
规律:
混合型的最大基本类型包括在成员变量中的struct或union中的变量(根据这个大小来对齐),而大小计算具体到每个struct和uion来根据上面的规律计算。
四、给出四个点判断正方形。
这题简单吗?关键是怎么在最短的时间内确定最快的方法来判定。
四条边相等是肯定的,那么判断垂直?感觉很麻烦,如果四个点是随机输入的话。可以利用距离的性质,即四条边相等,对角线相等。那么利用计算机的思想,两两的距离只有两种,而且这两种的比为一比根号2,数量一种为4,一种为2。这样程序就容易写了吧。
五、类的隐式转换
#include<stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
class Temp{
public:
int m_i;
Temp(int i){
m_i = i;
}
explicit Temp(char a);
};
void foo(Temp temp){
cout<<temp.m_i<<endl;
}
int main(){
//隐式转换
foo(20);
//这里呢?
foo('a');
system("PAUSE");
return 0;
}
注意标注隐转换的地方:
即函数foo需要Temp类做参数,但直接传入整数20可以吗?在代码中是可以的,因为Temp(int i)构造函数能通过整数构造Temp类,所以这里就发生了隐式转换,当整数传入foo的时候,自动调用整数参数的构造函数构造一个临时的类对象。
但foo('a')也可以吗?明明字符串参数的构造函数表示了explicit,是不能隐式转换的。实际上这里调用的是int型的构造函数实现转换的,将char型转换为int了。如果将整形的构造函数也加explicit,则编译不通过。