剑指Offer学习笔记(一)

来源:互联网 发布:足球黑色三分钟 知乎 编辑:程序博客网 时间:2024/06/05 20:27

下半年要找工作了,作为一个技术不牛、代码能力弱的小硕,表示很揪心,也为自己的编码能力深深的汗颜,也许自己并不太适合程序猿这个工作吧!

Anyway, 还是要好好复习和学习的,尤其是要锻炼自己的编码能力,希望可以找到理想的工作。希望可以通过记录博客来鞭策自己好好复习。

不管未来工作如何,掌握基础的专业知识,也是对一年后要结束的学生生涯的一个交代吧!fighting~~~

看书提供的代码,发现自己有这几个问题还没有搞明白。

1. _tmain和main的区别

_tmain()是windows提供的对unicode字符集和ANSI字符集进行自动转换用的程序入口点函数。是main的一个别名,在<stdafx.h>中有宏定义,即

#include <stdio.h> #include <tchar.h>,其中头文件<tchar.h>中有它的宏定义:

#define _tmain  main

预编译后,_tmain变成了main.

main()是标准C++函数入口,默认字符编码格式ANSI。

2.P24. 面试题1. 赋值运算符函数

#include <iostream>#include <string>using namespace std;class CMyString{public:CMyString(char* pData=NULL);CMyString(const CMyString& str);~CMyString(void);//声明返回值的类型为引用,才能允许连续赋值CMyString& operator = (const CMyString& str);void Print();private:char* m_pData;};CMyString::CMyString(char *pData){if (pData == NULL){m_pData = new char[1];m_pData[0] = '\0';}else{int length = strlen(pData);m_pData = new char[length + 1];strcpy(m_pData, pData);}}CMyString::~CMyString(){delete[]m_pData;}CMyString::CMyString(const CMyString& str){int length = strlen(str.m_pData);m_pData = new char[length + 1];strcmp(m_pData, str.m_pData);}CMyString& CMyString::operator=(const CMyString& str){/** 1.普通写法if (this == &str)return *this;delete[]m_pData;m_pData = NULL;//释放内存m_pData = new char[strlen(str.m_pData) + 1];//若内存不足则会导致new char抛出异常,m_pData会是空指针strcpy(m_pData, str.m_pData);return *this;*//** 2.考虑异常安全性写法,先创建临时实例,在交换临时实例和原来的实例* 然而运行结果并不太对。。输出的有问题。。????感觉这个有点问题。if (this != &str) {CMyString strTemp(str);// 需要交换,因为对象的两个实例空间上不能有交集char * pTemp = strTemp.m_pData;strTemp.m_pData = m_pData;m_pData = pTemp;}return *this;*//** 3. 考虑异常安全性,先用new分配新内容,再用delete释放已有内容*/if (this == &str){return *this;}char *pTemp = new char[strlen(str.m_pData) + 1];delete[]m_pData;m_pData = NULL;m_pData = pTemp;strcpy(m_pData, str.m_pData);return *this;}void CMyString::Print(){cout << m_pData << endl;}void Test1(){cout<<"测试1(把实例赋值给另一个实例)"<<endl;char* text = "hello test1";CMyString str1(text);CMyString str2;str2 = str1;cout << "预期结果:" << text << endl;cout << "实际结果:";str2.Print();cout << endl;}void Test2(){cout << "测试2(把实例赋值给自己)" << endl;char* text = "hello test2";CMyString str1(text);str1 = str1;cout << "预期结果:" << text << endl;cout << "实际结果:";str1.Print();cout << endl;}void Test3(){cout << "测试3(连续赋值)" << endl;char* text = "hello test3";CMyString str1(text);CMyString str2, str3;str3 = str2 = str1;cout << "str2预期结果:" << text << endl;cout << "str2实际结果:";str2.Print();cout << endl;cout << "str3预期结果:" << text << endl;cout << "str3实际结果:";str3.Print();cout << endl;system("pause");}int main(int argc, char* argv[]){Test1();Test2();Test3();return 0;}

其实关于内存不足的异常,感觉第二种方法是有问题的,我跑出来结果是不对的。还没有探索到原因。

3. 关于C++中的内存泄露

一般是指堆中的内存泄露。堆内存是手动malloc/realloc/new申请的,程序不会自动回收,需调用free或delete手动释放,否则会引起内存泄露【即要成对出现】。此外,还包括系统资料泄露,如socket连接使用完要释放。
申请和释放必须成对出现malloc/realloc对应free,new对应delete。前者不会运行构造/析构函数,后者会。
看被人总结了内存泄露的原因:
1. 编码错误:即堆内存malloc/realloc/new申请后,未手动释放。
2. 无主内存:申请后,指针指向内存起始地址,若丢失或修改该指针,申请的内存将丢失,且未释放。
3. 异常分支导致资源未释放
4. 隐式内存泄露:程序运行中不断申请内存,直到程序结束才释放。但因为很多程序运行时间长,来不及释放导致内存耗尽。
5. 类的析构函数为非虚函数:析构函数为虚函数,利用多态性调用指针指向对象的析构函数,而不是基类的析构函数。
详细内容在下面博客中有详细介绍:http://blog.csdn.net/kangroger/article/details/39317503


0 0
原创粉丝点击