歡聚時代在廣州的總部還是有點偏的,但是好在有專車接送,就方便多了。費話不多說,直接上題,下面是個人當時回答得不完整或是沒回答上來的問題!!!
問題1:#program pack(n)的作用
在搞清楚這個問題之前先看看在vs2013環境下佔用的字節大小:
int main(){
cout << "long float:"<<sizeof(long float) << endl;
cout << "float:" << sizeof(float) << endl;
cout << "long int:" << sizeof(long int) << endl;
cout << "long long int:" << sizeof(long long int) << endl;
cout << "double:" << sizeof(double) << endl;
cout << "long double:" << sizeof(long double) << endl;
cout << "long:" << sizeof(long) << endl;
return 0;
}
字節對齊(默認方式):
#pragma pack()
struct s1{
short a;
long b;
};
struct s2{
char c;
s1 d;
long long e;
};
struct s3{
int a;
int b;
char c;
double d;
};
int main(){
cout << "s1: "<<sizeof(s1) << endl;
cout << "s2: " <<sizeof(s2) << endl;
cout << "s3: " << sizeof(s3) << endl;
s3 node[2];
for (int i = 0; i < 2;i++){
printf("%p\n", &node[i].a);
printf("%p\n", &node[i].b);
printf("%p\n", &node[i].c);
printf("%p\n", &node[i].d);
cout << endl;
}
return 0;
}
輸出:
在這種情況下,每個元素的開始地址都是按照自己的長度對齊,在s3結構體裏面,元素a的偏移量爲0,b的偏移量爲4,c的偏移量爲8,d不能從9開始,只能從16開始,佔用
後續的8個字節,所以一共24字節!!!!!
修改:#pragma pack()->#pragma pack(4),輸出結果如下:
一旦我們指定了字節對齊數,那麼對齊量就是min{自身數據長度,n},很顯然,s3中最後一個元素的對齊量不是8而是4,所以d不能從9開始,但是可以從12開始(可以整除4),所以s3佔用的字節數是20字節!!!!
問題2:如何解決內存泄露
在博客上找到一篇相關文章http://blog.csdn.net/kangroger/article/details/39317503,其中有個辦法是內存泄露的關鍵就是記錄分配的內存和釋放內存的操作,看看能不能匹
配。跟蹤每一塊內存的聲明週期,例如:每當申請一塊內存後,把指向它的指針加入到List中,當釋放時,再把對應的指針從List中刪除,到程序最後檢查List就可以知道有沒有
內存泄露了。Window平臺下的Visual Studio調試器和C運行時(CRT)就是用這個原理來檢測內存泄露。
根據以上的思想我重載了全局new操作符和delete操作符,一旦有分配內存的操作,我們就將其保存在link的隊列中,一旦有釋放內存的操作,就將其中鏈表中刪除;如果申請
空間和釋放空間的操作時匹配的那麼,最終隊列爲空,這樣我們就可以模仿檢測內存泄露!!!!
下面是源碼:
#include<iostream>
#include<vector>
#include<list>
#include<fstream>
#include<string>
#include<set>
#include<map>
#include<algorithm>
#include<stack>
#include <typeinfo>
#include<bitset>
#include<cstdio>
#include <stdarg.h>
#include<functional>
using namespace std;
class base{
public:
int a;
int b;
base(){
a = 1;
b = 2;
}
};
typedef struct mem{
void *ptr;
struct mem *next;
mem() :ptr(NULL){};
}node, *link;
static link head = NULL;
void* operator new(size_t n){
cout << "this is a overload new!"<< endl;
void *p = malloc(n);
if (!p)cout << "out of memory!"<< endl;
link temp = (link)malloc(sizeof(mem));
temp->ptr = p;
temp->next = NULL;
if (head == NULL)head = temp;
else {//將其插入到head指針中,採用頭插法
temp->next =head;
head = temp;
}
return p;
}
void operator delete(void *p){
cout << "this is a overload delete!" << endl;
if (head != NULL){
link temp;
if (head->ptr == p){//和鏈表的頭結點相等
temp = head;
head = head->next;
free(temp->ptr);
free(temp);
return;
}
link now = head;
while (now->next != NULL&&now->next->ptr != p)now = now->next;
//處理相關結點
temp = now->next;//找到匹配的
now->next = now->next->next;
free(temp->ptr);
free(temp);
return;
}
}
int main(){
base *ptr = new base;
base *ptr1 = new base;
delete ptr1;
delete ptr;
/*
這裏是你的代碼......
*/
//記得head一定是放在程序的最後位置
if (head != NULL)cout << "memory leak!"<< endl;
return 0;
}
測試
我們只釋放ptr或者ptr1其中的一個:
<pre name="code" class="cpp">int main(){
base *ptr = new base;
base *ptr1 = new base;
delete ptr1;
//delete ptr;
/*
這裏是你的代碼......
*/
//記得head一定是放在程序的最後位置
if (head != NULL)cout << "memory leak!"<< endl;
cout << "the leaked memory start at:0x"<<head->ptr<< endl;
return 0;
}
測試結果:
綜上所述,面試的過程中會被經常問到的關於內問題有內存溢出,內存泄露,懸垂指針(野指針,設置一個智能指針類,添加一個計數器,詳情參見我的博客:點擊打開鏈接)