1、在main执行之前和之后执行的代码可能是什么?
main函数在执行前,主要就是初始化系统相关资源:
__attribute__((constructor))main函数执之后:
2、结构体内存对齐问题?
//但是alignas在某些情况下是不能使用的,具体见下面的例子://
#include
using namespace std;
/*
char 1B=8bit = -2^8 ~ 2^8-1
int 4B=32bit = -2^31 ~ 2^31-1
long long 8B
float 4B
double 8B
*/
typedef unsigned char uint8_t
typedef unsigned short int uint16_t
typedef unsigned int uint32_t
//alignas生效情况
struct Info{
uint8_t a;//unsigned char
uint16_t b;//unsigned short int
uint8_t c;//unsigned int
};
cout<<sizeof(Info)<<endl;
cout<<alignof(Info)<<endl;//类型对齐alignof
struct alignas(4)Info2{//结构体对齐alignas
uint8_t a;
uint16_t b;
uint8_t c;
};
cout<<sizeof(Info2)<<endl;//8 4+4
cout<<alignof(Info2)<<endl;//4
//alignas将内存对齐调整为4个字节。所以sizeof(Info2)的值变为了8//
//alignas失效的情况
struct Info{
uint8_t a;
uint32_t b;
uint8_t c;
};
cout<<sizeof(Info2)<<endl;//12 4+4+4
cout<<alignof(Info2)<<endl;//4(类型对齐)
//若alignas小于自然对齐的最小单位,则被忽略//如alignas(1),默认uint16_t还是2
//如果想使用单字节对齐的方式,使用alignas是无效的。应该使用#pragma pack(push,1)或者使用__attribute__((packed))
//可以使用#pragma pack(4) ,最后又想使用默认对齐方式时,可以使用#pragma pack() ;
#if defined(__GNC__) || defined(__GNUC__)
#define ONEBYTE_ALIGN __attribute__((packed))
#elif defined(_MSC_VER)
#define ONEBYTE_ALIGN
#define pack(push,1)
#endif
struct Info{
uint8_t a;
uint16_t b;
uint8_t c;
}ONEBYTE_ALIGN;
#if defined(__GNUC__) || defined(__GNUG__)
#undef ONEBYTE_ALIGN
#elif defined(_MSC_VER)
#pragma pack(pop)
#undef ONEBYTE_ALIGN
#endif
cout<<sizeof(Info)<<endl;//6 1+4+1
cout<<alignof(Info)<<endl;//6
//确定结构体中每个元素大小可以通过下面这种方法
/*#pragma pack(push) //保存对齐状态
#pragma pack(4)//设定为4字节对齐
相当于 #pragma pack (push,4) */
#if defined(__GNUC__) || defined(__GNUG__)
#define ONEBYTE_ALIGN __attribute__((packed))
#elif defined(_MSC_VER)
#define ONEBYTE_ALIGN
#pragma pack(push,1)//#pragma pack (push,1)作用:是指把原来对齐方式设置压栈,并设新的对齐方式设置为一个字节对齐
#endif
/**
*
* 0 1 3 6 8 9 15
* +-+---+-----+---+-+-------------+
* | | | | | | |
* |a| b | c | d |e| pad |
* | | | | | | |
* +-+---+-----+---+-+-------------+
*
*/
struct Info {
uint16_t a : 1;
uint16_t b : 2;
uint16_t c : 3;
uint16_t d : 2;
uint16_t e : 1;
uint16_t pad : 7;
} ONEBYTE_ALIGN;
#if defined(__GNUC__) || defined(__GNUG__)
#undef ONEBYTE_ALIGN
#elif defined(_MSC_VER)
#pragma pack(pop)//#pragma pack(pop)作用:恢复对齐状态
#undef ONEBYTE_ALIGN
#endif
std::cout << sizeof(Info) << std::endl; // 2
std::cout << alignof(Info) << std::endl; // 1
//这种处理方式是 alignas 处理不了的。
3、指针和引用的区别
void test(int* p)//为改变p的地址
{
int a=1;
p=&a;
cout<<p<<" "<<*p<<endl;
}
void main(void)
{
int* p=NULL;
test(p);
if(p==NULL) cout<<"指针p为NULL"<<endl;'
}
//====================
void testPTR(int* p)//函数内部栈申请的内存,用完即释放
{
int a = 12;
p = &a;
}
void testREFF(int& p)
{
int a = 12;
p = a;
}
void main(void)
{
int a = 10;
int* b = &a;
testPTR(b);
cout << a << endl;// 10
cout << *b << endl;// 10
a = 10;
testREFF(a);
cout << a << endl;//12
}
//在编译器看来,int a=10;int &b=a;
//等价于:int* const b=&a;//b的地址不可变
//等价于 *b = 20; 自动转换为指针和自动解引用
//就是我们呢可以把引用看成对变量的一种标签,同一个变量值不通过名字
4、堆和栈的区别

5、区别以下指针类型?
int *p[10]
int (*p)[10]
int *p(int)
int (*p)(int)
6、基类的虚函数表存放在内存的什么区,虚表指针vptr的初始化时间
7、new / delete 与 malloc / free的异同
int *p=new float[2];//error
int *p=(int*)malloc(2*sizeof(double));//编译无错误
8、new和delete是如何实现的?
9、malloc和new的区别?
int* p=(int*)malloc(200*sizeof(int));10、宏定义和函数有何区别?