Liang’s Dev Zone

坚持,敏感,创新,平衡,勤奋,聪明,开阔,诚信!

[C++ Primer Reading]动态内存分配和指针

leave a comment »

在C++中对象可以:

  • 静态分配——即编译器在处理程序源代码时分配。
  • 动态分配——即程序执行时调用运行时刻库函数来分配。

这两种内存分配方法的主要区别是:效率与灵活性之间的平衡准则不同。

出于静态内存分配是:在程序执行之前进行的因而效率比较高,但是它缺少灵活性,它要求在程序执行之前就知道所需内存的类型和数量,例如利用静态分配的字符串数组我们无法很容易地处理和存储任意的文本文件,一般来说存储未知数目的元素需要动态内存分配的灵活性。

静态与动态内存分配的两个主要区别是:

  1. 静态对象是有名字的变量,我们直接对其进行操作,而动态对象是没有名字的变量,我们通过指针间接地对它进行操作。
  2. 静态对象的分配与释放由编译器自动处理,程序员需要理解这一点,但不需要做任何事情相反动态对象的分配与释放,必须由程序员显式地管理相对来说比较容易出错,它通过new 和delete 两个表达式来完成。

Written by liangdev

June 24, 2009 at 3:12 am

Posted in Cpp

SDET 面试技巧

leave a comment »

发现一个不错的英文ppt,翻译成中文,分享给大家

image

Written by liangdev

June 4, 2009 at 4:13 am

Posted in test

[Tools]Log Parser 分析 IIS log

leave a comment »

Microsoft Logparser,用来分析log的工具,使用SQL语法的查询接口,基本上我常用的只有IIS log,而且从下图来看,可以导出很多类型的数据形式,挺实用的.

logparser_architecture.gif

Log parser arch

下载地址 : http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07&displaylang=en

reference

Written by liangdev

April 27, 2009 at 9:33 am

Posted in Uncategorized

Stress test via VSTS

leave a comment »

以前,不知道性能测试(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个并发用户的情景。

Written by liangdev

March 17, 2009 at 8:29 am

Posted in Uncategorized

LiangLib Project

leave a comment »

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

Written by liangdev

October 30, 2008 at 6:40 am

Posted in architecture

[LVCFCP] A Prelude to Pointers

with one comment

引用原文地址: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 the
    
           data 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

Written by liangdev

October 29, 2008 at 9:20 am

Posted in Cpp

[LVCFCP] A Beginner’s Guide to Pointers

with one comment

原文引用地址: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
  • SUMMARY
    1. 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).
    2. You can get the address of any variable by adding an ampersand (&) in front of it, i.e. pNumber = &my_number.
    3. The asterisk, unless in a declaration (such as int *number), should be read as “the memory location pointed to by.”
    4. The ampersand, unless in a declaration (such as int &number), should be read as “the address of.”
    5. You can allocate memory using the new keyword.
    6. Pointers MUST be of the same type as the variables you want them to point to; so, int *number will not point to a MyClass.
    7. You can pass pointers to functions.
    8. You must delete memory that you have allocated by using the delete keyword.
    9. You can get a pointer to an array that already exists by using &array[0];.
    10. You must delete an array that is dynamically allocated using delete[], not just delete.
  • 看看指针和引用的区别:
  • 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
    
    }
    是吧?
     

Written by liangdev

October 29, 2008 at 8:41 am

Posted in Cpp

[LVCFCP] The three major concepts of C++ – Part 1: Classes

with one comment

原文章引用地址: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 only
    
        void display_name(void);
    
    };
    
    
    
    // the :: is the scope resolution operator
    
    void 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:
    
        //一般的成员变量

    Written by liangdev

    October 29, 2008 at 8:03 am

    Posted in Cpp

    [LVCFCP] Why I Chose C++

    with one comment

    引用原文地址:http://www.codeproject.com/KB/cpp/whycplusplus.aspx (仅作学习参考用)

    quick notes:

    • 操作符重载(Operator Overloading)
      class CVeryLong
      
        {
      
        public:
      
            // 默认构造器,初始化成员变量为0
      
            CVeryLong(){ 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 true
      
             vl1 > vl2 is false
      
             vl1 == vl2 is false
      
             vl1 < vl3 is false
      
             vl1 > vl3 is false
      
             vl1 == 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 contents
      
         memcpy( m_pValue, refValue.GetBuffer(), sizeof(long) * m_nValues );
      
         return *this;
      
      }
    • 异常的处理:WINDOWS NT提供了一种成熟的能力称为SEH(Structured Exception Handling),
      看下面的异常处理的代码:
    • 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 loop
      
              y--; // continue via outer loop
      
          }
      
      }
      
      
      
      DWORD dwStop = ::GetTickCount();
      
      DWORD dwDiff = dwStop - dwStart;
      
      CString csMessage;
      
      csMessage.Format( "mSec = %d", dwDiff );
      
      cout << (LPCTSTR)csMessage << endl;
       
      运行结果:
      Divide by zero
      
      mSec = 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 shown
        
            private:
        
                KEY m_key;
        
                DATA m_data;
        
                BALANCE m_Bal; // -1..1 current balance data for this node
        
                PNODE 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 shown
        
        
        
        private:
        
            CNode* m_pRoot;
        
            bool m_bHeightChange;
        
            int m_nSize;
        
        };
        
        
        

    -Still need to develop-

    Written by liangdev

    October 29, 2008 at 2:16 am

    Posted in Cpp

    3 Days to Learn VC from Codeproject -PAUSE

    leave a comment »

    Under List of C++ / MFC / STL – Beginners (初学者)
    { Begin : 29/10/2008  | Expected end : 31/10/2008 }

    文章列表:

    最近的项目需要用到C++,现学现用吧。

    有用的C++学习资源网站:

    Written by liangdev

    October 28, 2008 at 9:11 am

    Posted in Cpp

    Follow

    Get every new post delivered to your Inbox.