[C++ Primer Reading]动态内存分配和指针
在C++中对象可以:
- 静态分配——即编译器在处理程序源代码时分配。
- 动态分配——即程序执行时调用运行时刻库函数来分配。
这两种内存分配方法的主要区别是:效率与灵活性之间的平衡准则不同。
出于静态内存分配是:在程序执行之前进行的因而效率比较高,但是它缺少灵活性,它要求在程序执行之前就知道所需内存的类型和数量,例如利用静态分配的字符串数组我们无法很容易地处理和存储任意的文本文件,一般来说存储未知数目的元素需要动态内存分配的灵活性。
静态与动态内存分配的两个主要区别是:
- 静态对象是有名字的变量,我们直接对其进行操作,而动态对象是没有名字的变量,我们通过指针间接地对它进行操作。
- 静态对象的分配与释放由编译器自动处理,程序员需要理解这一点,但不需要做任何事情相反动态对象的分配与释放,必须由程序员显式地管理相对来说比较容易出错,它通过new 和delete 两个表达式来完成。
[Tools]Log Parser 分析 IIS log
Microsoft Logparser,用来分析log的工具,使用SQL语法的查询接口,基本上我常用的只有IIS log,而且从下图来看,可以导出很多类型的数据形式,挺实用的.

Log parser arch
reference
Stress test via VSTS
以前,不知道性能测试(Performance test),压力测试(Stress test)区别和概念。最近闲来无事,就摊了一个压力测试活儿,业务很简单,主要是理解压力怎么测,测什么,有什么用,什么时候用,怎么用。出个报告,做个PPT。
首先说下压力测试的工具,有Load Runner,VSTS,我现在只能用VSTS,所以就VSTS的相关技术来说。
先说一下参考资料,关于VSTS测试方面的内容,在MSDN上面已经有详细的介绍了(中文的哦)。
LINK:http://msdn.microsoft.com/zh-cn/library/ms182409(VS.80).aspx
还有Ed Glas的blog,总结了一些VSTS Load Test的相关资料
LINK:http://blogs.msdn.com/edglas/pages/content-index-for-web-tests-and-load-tests.aspx
以上资源基本上能够涵盖VSTS Load Test所有概念和方法。
Why Stress Test
测试,我的理解,就是把产品在真实环境里面需要面临的一些场景情况事先模拟一遍,然后心里有了底之后,就敢拿出去忽悠吹嘘了。当然,最基本的就是手工测试。
同样,压力测试也是模拟实际场景来进行测试的,一个服务器,可能在早上8点有100个并发,慢慢就会人多起来,然后到中午12点会有一个高峰,持续到1点,然后下午三点和晚上7点多又迎来一个高峰。这都是基于用户的行为分析来确定场景的。
比如说银行系统,在中午12点的时候,并发有200个请求来访问在线银行,到1点期间差不多都保持在200多个请求并发的水平,对服务器的要求就很高,不能让Server在这一个小时崩掉了。所以要事先模拟一下,以防在真实环境中出乱子,搞得很被动。
压力测试需要明确它的概念,压力测试的目标要让系统能够在固定的时间内,承受起一定的压力并且运行良好,时间是有限的,一般几个小时就差不多能观察出系统压力承受能力了,不需要压个几天几夜的。要运行良好,就是运行的过程中不能有错误。
VSTS可以模拟在这1个小时内200个并发用户的情景。
…
LiangLib Project
Overview
LiangLib我平时使用.net工作编程的时候常用的功能,把他们收集起来封装在LiangLib里面,以后用到可以经常拿出来参考。LiangLib是基于.net平台无限递归的开发的库,我会不断的加入新的功能,新的用法,然后让它能够适用于更多的项目,更多的的地方。
Feature List
- Common Regex Function (正则表达式常用的方法) | under construction
- Configuration Manage (配置文件管理) | under construction
- ini file configuration,include write,read and delete specified Section/key/value (ini 配置文件的读写) | done
- xml file configuration | under construction
- Multiple Thread/Thread Pool Manage:多线程和线程池的管理 | under construction
- Log Helper:记录Log的组件 | under construction
- Algorithm:常用到的数据结构 | under construction
- Web Handler Wrapper:常用到的web程序,如:http handler,socket | under construction
【under construction (进行中 ),done (已完成)】
Develop
Manage(进度管理):zoho project
Source Code Host:Google Code
Reference
- cnblogs.com
- codeproject.com
[LVCFCP] A Prelude to Pointers
引用原文地址:http://www.codeproject.com/KB/cpp/pointerprelude.aspx
quick notes:
- 术语:
- Value – The actual value of the specified data type.
- Pointer To – A pointer to the memory location of a specified data type.
- Address Of – The physical memory address of a given data type.
- Reference To – A reference to a given data type, NOT a copy of it. (C++ only)
- Dereferenced Value – The value of the data type pointed to by a pointer.
- 看这段代码怎么用引用和指针的:
// Initialize a variable, 'x', of type 'int' to the 'value' 5.int x = 5;// Initialize a variable, 'px' of type 'pointer to int' to the value of// 'the address of' x.int* px = &x;---- --
| |
| |- This is read "address of" x|
|- Notice I put the * modifier after int, not before px (int* px not
int *px). The compiler doesn't care, however I am modifying thedata type, not the variable. Thus I remain consistent to my technique.// Now initialize a variable 'ref_to_x' as a reference to x.int& ref_to_x = x;----
|
|- Again, I keep the modifier with what I am modifying.
// Initialize a variable,'deref_px' of type 'int' to the 'dereferenced// value' of px.int deref_px = *px;---
|
|- Notice in this case, the * is with px, because that is
what I'm modifying.
- 指针的指针
int x = 7;int* px = &x;int** ppx = &px;printf("\nx = %d", x );printf("\n*px = %d", *px );printf("\n**ppx = %d", **ppx);结果是:7 7 7
[LVCFCP] A Beginner’s Guide to Pointers
原文引用地址:http://www.codeproject.com/KB/cpp/pointers.aspx
quick notes:
- 看看这个陷阱
#include <stdio.h>int *pPointer;void SomeFunction();{int nNumber;nNumber = 25;// make pPointer point to nNumber:pPointer = &nNumber;}void main(){SomeFunction(); // make pPointer point to something// why does this fail?printf("Value of *pPointer: %d\n", *pPointer);}
看出什么错儿了吗?nNmber是局部变量,在SomeFunction之后就销毁了,pPointer就不会指向值25的nNumber了,不知道指哪儿去了
#include <stdio.h>int *pPointer;void SomeFunction(){// 让pPointer指向一个新的int类型内存pPointer = new int;*pPointer = 25;}void main(){SomeFunction(); // 让pPoiner指向某个地方printf("Value of *pPointer: %d\n", *pPointer);}这个程序仍有问题。需要加上一行
delete pPointer;因为,如果不删除这个指针,这块内存不会释放,会产生内存泄露。内存会慢慢泄露,知道程序关闭。
#include <stdio.h>void AddFive(int Number){Number = Number + 5;}void main(){int nMyNumber = 18;printf("My original number is %d\n", nMyNumber);AddFive(nMyNumber);printf("My new number is %d\n", nMyNumber);}======================================#include <stdio.h>void AddFive(int* Number){*Number = *Number + 5;}void main(){int nMyNumber = 18;printf("My original number is %d\n", nMyNumber);AddFive(&nMyNumber);printf("My new number is %d\n", nMyNumber);}=====================================
第一个程序中,nMyNumber指不会改变,因为AddFive里面处理的是一个拷贝,第二个里面nMyNumber值会改变
class MyClass{public:int m_Number;char m_Character;};void main(){MyClass *pPointer;pPointer = new MyClass;pPointer->m_Number = 10;pPointer->m_Character = 's';delete pPointer;}
#include <stdio.h>void main(){int Array[3];Array[0] = 10;Array[1] = 20;Array[2] = 30;int *pArray;pArray = &Array[0];printf("pArray points to the value %d\n", *pArray);}
void main(){int number;int *pNumber = number;delete pNumber; // 错 - *pNumber 没有使用new来分配内存}
int& Number = myOtherNumber;Number = 25;-----------int* pNumber = &myOtherNumber;*pNumber = 25;
这两段程序是一样的,Number是MyOtherNumber内存地址的引用,Number改变,MyOtherNumber也改变,pNumber又指向myOtherNumber内存,*pNumber赋值25,myOtherNumber值也是25
- Pointers are variables that point to an area in memory. You define a pointer by adding an asterisk (
*) in front of the variable name (i.e.int *number). - You can get the address of any variable by adding an ampersand (
&) in front of it, i.e.pNumber = &my_number. - The asterisk, unless in a declaration (such as
int *number), should be read as “the memory location pointed to by.” - The ampersand, unless in a declaration (such as
int &number), should be read as “the address of.” - You can allocate memory using the
newkeyword. - Pointers MUST be of the same type as the variables you want them to point to; so,
int *numberwill not point to aMyClass. - You can pass pointers to functions.
- You must delete memory that you have allocated by using the
deletekeyword. - You can get a pointer to an array that already exists by using
&array[0];. - You must delete an array that is dynamically allocated using
delete[], not justdelete.
int myFirstNumber = 25;int mySecondNumber = 20;int &myReference = myFirstNumber;myReference = mySecondNumber;printf("%d", myFristNumber);
输出结果是:20。也就是不能改变一个定义好的引用对象。不能吧myReference改变到mySecondNumber的引用上。在一个类里,引用的值应该这样设置
CMyClass::CMyClass(int &variable) : m_MyReferenceInCMyClass(variable){// constructor code here}
是吧?
[LVCFCP] The three major concepts of C++ – Part 1: Classes
原文章引用地址:http://www.codeproject.com/KB/cpp/beginnerclass.aspx
quick notes:
- 跟Java和C#的类概念一样,需要注意的,接口写在.h文件里,实现写在.cpp里,类里用private: public:来组织和定义变量和函数方法,属性和方法都可以用”.”来调用操作,指针用“->”来操作属性和方法。
- 构造函数和析构函数
构造函数用的比较多了,就不多讲了,他也没讲出什么,详细讲讲析构函数吧:
析构函数在程序的末尾,用来销毁对象用的,如果没有写,就给一个默认的。 - 内联和外联函数,看起来就像是在类体外面来定义函数
const int SIZE = 40;class employee{private:char name[SIZE];public:employee() //constructor{strncpy(name, "Unemployed", SIZE);}~employee() //destructor{}void set_name(char[SIZE]); //function declarations onlyvoid display_name(void);};// the :: is the scope resolution operatorvoid employee::set_name(char arg_name[SIZE]){strncpy(name, arg_name, SIZE);}void employee::display_name(void){cout << name;}
When to use private://防止发生类以外的改变When to use protected://私有变量用在继承和组合里面的时候When to use public://一般的成员变量
[LVCFCP] Why I Chose C++
引用原文地址:http://www.codeproject.com/KB/cpp/whycplusplus.aspx (仅作学习参考用)
quick notes:
- 操作符重载(Operator Overloading)
class CVeryLong{public:// 默认构造器,初始化成员变量为0CVeryLong(){ m_lHigh = m_lLow = 0; }// 构造器,初始化成员变量值CVeryLong( long lHigh, long lLow ){ m_lHigh = lHigh; m_lLow = lLow; }
virtual ~CVeryLong(){}; // 析构
void SetHighValue( long lValue ){ m_lHigh = lValue; }
long GetHighValue(){ return m_lHigh; }
void SetLowValue( long lValue ){ m_lLow = lValue; }
long GetLowValue(){ return m_lLow; }
BOOL operator < ( CVeryLong& refValue ) // 少于 操作符
{if ( m_lHigh < refValue.GetHighValue()) return TRUE;
else if ( m_lHigh > refValue.GetHighValue()) return FALSE;
else if ( m_lLow < refValue.GetLowValue()) return TRUE;
else return FALSE; // >=
}
BOOL operator > ( CVeryLong& refValue ) // 大于 操作副
{if ( m_lHigh > refValue.GetHighValue()) return TRUE;
else if ( m_lHigh < refValue.GetHighValue()) return FALSE;
else if ( m_lLow > refValue.GetLowValue()) return TRUE;
else return FALSE; // <=
}
BOOL operator == ( CVeryLong& refValue ) // 等于 操作符
{return m_lHigh == refValue.GetHighValue()&& m_lLow == refValue.GetLowValue();
}
private:long m_lLow;long m_lHigh;};
CVeryLong 有两个long类型的成员变量来表示一个单独的64位int类型数据,这个类对<,>,=操作符进行重载实现64位int类的方法,但是这个类还有其他的方法没有实现。上面类的而实现:{CString csText;
CVeryLong vl1( 1, 2 ), vl2( 1, 3 ), vl3;
cout << "vl1 is (1, 2)" << endl;cout << "vl2 is (1, 3)" << endl;cout << "vl3 is (1, 2)" << endl;csText = "vl1 < vl2 is ";csText += vl1 < vl2 ? "true" : "false";
cout << (LPCTSTR)csText << endl;
csText = "vl1 > vl2 is ";csText += vl1 > vl2 ? "true" : "false";
cout << (LPCTSTR)csText << endl;
csText = "vl1 = = vl2 is ";csText += vl1 == vl2 ? "true" : "false";
cout << (LPCTSTR)csText << endl;
csText = "vl1 < vl3 is ";csText += vl1 < vl3 ? "true" : "false";
cout << (LPCTSTR)csText << endl;
csText = "vl1 > vl3 is ";csText += vl1 > vl3 ? "true" : "false";
cout << (LPCTSTR)csText << endl;
csText = "vl1 = = vl3 is ";csText += vl1 == vl3 ? "true" : "false";
cout << (LPCTSTR)csText << endl;
}
运行结果:
vl1 is (1, 2)
vl2 is (1, 3)
vl3 is (1, 2)
vl1 < vl2 is truevl1 > vl2 is falsevl1 == vl2 is falsevl1 < vl3 is falsevl1 > vl3 is falsevl1 == vl3 is true - 默认的赋值操作将会拷贝成员变量,跟以前一样,只是偶尔(only now)有两个指针指向同一块儿分配内存,当第一块个指针析构第一对象,他将会正确的释放内存。当第二块内存对象的析构器运行的时候,释放这块内存就会产生:BUG和CRASH(崩溃)。
等号(=)的重载可以这样写:
CVeryVeryLong operator = ( CVeryVeryLong& refValue ) // 赋值操作符{delete [] m_pValues; // 释放之前的值m_nValues = refValue.GetNumberOfValues(); // 需要是定义好的m_pValues = new long[ m_nValues ]; // 分配新的值// GetBuffer() in the following line needs to be defined// copy the array contentsmemcpy( m_pValue, refValue.GetBuffer(), sizeof(long) * m_nValues );return *this;}
看下面的异常处理的代码:
DWORD dwStart = ::GetTickCount(); // 用于计时,单位毫秒const int x = 1000000;const int xEnd = -x;int y = x;int z;while ( y > xEnd ){try{while ( y > xEnd )z = x / y--; // divide protected by exception}catch (...){cout << "Divide by zero" << endl; // trapped out of inner loopy--; // continue via outer loop}}DWORD dwStop = ::GetTickCount();DWORD dwDiff = dwStop - dwStart;CString csMessage;csMessage.Format( "mSec = %d", dwDiff );cout << (LPCTSTR)csMessage << endl;
运行结果:
Divide by zeromSec = 491
- 方法模板
template <class T> T& Max( T& a, T& b ){if ( a > b ) return a; else return b;}
使用:
int n1 = 5, n2 = 10, n3;float f1 = 5.1f, f2 = 10.5f, f3;CVeryLong vl1( 1, 2 ), vl2( 2, 15 ), vl3; // remember CVeryLong?n3 = Max( n1, n2 );f3 = Max( f1, f2 );vl3 = Max( vl1, vl2 );CString csMessage;csMessage.Format( "n3 = %d, f3 = %f, vl3 = (%d, %d)",n3, f3, vl3.GetHighValue(), vl3.GetLowValue() );cout << (LPCTSTR)csMessage << endl;
结果:
n3 = 10, f3 = 10.500000, vl3 = (2, 15)
STL和ATL都是非常常用的用于创建小程序和高重用性的库。
template<class KEY, class ARG_KEY, class DATA, class ARG_DATA>class CTree{private:typedef enum{ balLeft = -1,balEven,balRight,} BALANCE;class CNode;typedef CNode* PNODE;class CNode // container to hold the data and hide the balancing details{public:CNode( ARG_KEY key, ARG_DATA data );// additional members not shownprivate:KEY m_key;DATA m_data;BALANCE m_Bal; // -1..1 current balance data for this nodePNODE m_pLeft;PNODE m_pRight;};CTree(){ m_pRoot = 0; m_nSize = 0; m_bHeightChange = false; }virtual ~CTree();bool GetFirst( ARG_KEY key, ARG_DATA data );bool GetLast( ARG_KEY key, ARG_DATA data );bool GetNext( ARG_KEY key, ARG_DATA data );bool GetPrev( ARG_KEY key, ARG_DATA data );bool Add( ARG_KEY key, ARG_DATA data );ARG_DATA operator[]( ARG_KEY key );bool Delete( ARG_KEY key );// additional members not shownprivate:CNode* m_pRoot;bool m_bHeightChange;int m_nSize;};
-Still need to develop-
3 Days to Learn VC from Codeproject -PAUSE
Under List of C++ / MFC / STL – Beginners (初学者)
{ Begin : 29/10/2008 | Expected end : 31/10/2008 }
文章列表:
- 【Day 1】An introduction to bitwise operators :介绍位操作,内存细节,C++编程需要掌握的一些基础概念吧。| notes | complete
- 【Day 1】A Beginner’s Guide to Pointers :介绍指针的基础用法,指针是最头疼的东东了,这个得好好看看 | notes | complete
- 【Day 1】A Prelude to Pointers :接着上一篇内容来继续介绍指针。| notes | complete
- 【Day 1】A serialization primer – Part 2 not begin
- 【Day 1】The three major concepts of C++ – Part 1: Classes :C++的三个主要的概念,第一部分:类。| notes | complete
- 【Day 1】Synchronization in Multithreaded Applications with MFC not begin
- 【Day 1】A Beginners guide to Templates – Part 1 not begin
- 【Day 2】A serialization primer – Part 1 not begin
- 【Day 2】Think before you code, Virtual Functions in C++ not begin
- 【Day 2】Bitwise Operation Explained not begin
- 【Day 1】Why I Chose C++ :为什么要选择C++呢?这里介绍了一些C++的特性。| notes | complete
- 【Day 2】MFC under the hood not begin
- 【Day 2】A serialization primer – Part 3 not begin
- 【Day 2】Introduce Yourself to VC++ not begin
- 【Day 3】Different Styles of Programming not begin
- 【Day 3】A beginner’s guide to Object Orientation not begin
- 【Day 3】Using namespaces properly not begin
- 【Day 3】A Beginners guide to Templates – Part 2 not begin
- 【Day 3】Template based programming not begin
- 【Day 3】Const illustration in C++ not begin
- 【Day 3】Memory leak detection in C++ not begin
- 【Day 3】Learn Queue with some exceptional Handling not begin
最近的项目需要用到C++,现学现用吧。
有用的C++学习资源网站:
- http://www.cplusplus.com/ C++.com,一个基础的C++入门网站,里面也有很多基础的东西。
- http://www.learncpp.com/
- http://newdata.box.sk/bx/c/htm/ch08.htm 21天学会C++,扯淡!