壹、 靜態陣列 與 動態陣列 監看

  

針對一般靜態陣列而言,大多數附 debug 功能之 IDE 都有此功能,且查看非常方便。

#include <stdio.h>

int main()
{
    int x[2]={1,2};
    int y[2][3] = {{1,2} , {3,4}};
    int z[2][3][4] = {
        { {1,2,3,4}    ,{5,6,7,8}    ,{9,10,11,12} },
        { {13,14,15,16},{17,18,19,20},{21,22,23,24} }
    };
    return 0; /* break point here */
}

 

 Watch_039.png    

 

甚至連 struct 都可以看

 

#include <stdio.h>
#include <stdlib.h>
typedef struct tagPoint{
    int x, y;
}Point;

int main()
{
    Point x[3] = { {1,1},{2,2,},{3,3}};    
    return 0; /* break point here */
}

 

Watch_040.png   

 

但有較麻煩之地方,用 malloc 或 new 這種方式,只能顯示其 pointer ,沒辦法追到所有的 allocation memory

 

#include <stdio.h>
#include <stdlib.h>
#define N 3
int main()
{
    int i;
    int *arr=(int*)malloc(sizeof(int)*N);
    for(i=0; i!=N; ++i) arr[i] = 100+i;
    return 0; /* break point here */
}

 

Watch_041.png

若只有小批量記憶體的話,倒是可在監看式裡手動加上去

Watch_042.png

要觀查以 malloc / new 出來之 struct 也一樣

 

#include <stdio.h>
#include <stdlib.h>
#define N 3

typedef struct tagPoint{
    int x, y;
}Point;
int main()
{
    int i;
    Point *arr=(int*)malloc(sizeof(Point)*N);
    for(i=0; i!=N; ++i) 
        arr[i].x = arr[i].y = i+100;
    return 0;  /* break point here */
}

 

Watch_043.png

 


 

貮、 容器監看

 

對於 C++ STL Container (vector、list、deque),這點 Visual C++ 做的倒比大多 IDE 還好,

一些 IDE 沒辦法正常觀看 Constainer 內含值,要解決的話可能還要再找其他 library。

以 vector 為例,可輕易看到 vector 內含值,下述以一維 vector 為例。

Watch_044.png    

 

也可看到多維之 vector

#include <vector>
using std::vector;

typedef vector<int> v2;

int main()
{
    const size_t x=2, y=3;
    vector< v2 > ivec2;
    for(size_t i=0; i!=x; ++i) {
        vector<int> ivec;
        for(size_t j=0; j!=y; ++j){
            ivec.push_back(i*y+j);
        }
        ivec2.push_back(ivec);
    }
    return 0;  /* break point here */
}

 

Watch_045.png

 

自然 list 也不在話下

 

#include <list>
using std::list;

int main()
{
    list<int> li;
    for(size_t i=0; i!=5; ++i)
        li.push_front(i);
    return 0; /* break point here */
}

 

Watch_046.png


 

參、 類別記憶體監看

 

一些類別會有記憶體管理之動作,考慮以下程式碼

 

#include <iostream>
using namespace std;

class Array{
private:
    size_t cnt;
    int *ptr;
public:
    Array(size_t _cnt)
    {
        cnt = _cnt;
        ptr = new int[cnt];
        for(size_t i=0; i!=_cnt; ++i)
            ptr[i]=i+100;
    }

    ~Array()
    {
        delete [] ptr;
    }

    int operator[] (int index)
    {
        return ptr[index];
    }
};

int main()
{
    Array arr(3);
    return 0/* break point here */
}

 

注意到,上述欲複載足標運算子,企圖在監看式中,以 arr[i] 方式呈現出該物件之內含值。但實際上並沒那麼順

Watch_047.png

原因在於,上述之物件 Array,內部記憶體乃是用 new / malloc 方式完成,故只能追溯到 pointer,沒辦法追溯到完整之 Allocate memory。在監看式裡用點小技巧試試

Watch_048.png

很遺憾的,雖已複載了足標運算子,但用 arr[0]、arr[1]、arr[2] 並無法顯示其內含值。這部份可想而知,上述監看式之設立,較適用於

Array *arr = new Array[3];

之方式。再改一下監看式之內容

Watch_049.png

這次便全都顯示正常。但若 class 在設計時,不用 malloc / new ,而是直接讓 vector 管理記憶體的話

 

#include <iostream>
#include <vector>
using namespace std;

class Array{
private:
    vector<int> v;
    size_t cnt;
public:
    Array(size_t _cnt)
    {
        cnt = _cnt;
        for(size_t t=0; t!=cnt; ++t)
            v.push_back(t);

    }

    int operator[] (int index)
    {
        return v.at(index);
    }
};

int main()
{
    Array arr(3);
    return 0; /* break point here */
}

 

Watch_050.png

 這裡顯示便正常了。


注意到,上述在監看式裡,不論是 array 或 container,

都可在監看式裡直接修改記憶體內含值。

  

另,由於 Visual Studio IDE 做得算強大,上述像是 container 、class 之監看,

其他 IDE 未必做得出來。

而關於一般用 malloc / new 之方式如何觀查記憶體之位址變化 ,

(除了用 printf、cout、Debug.Print 之方式外)

小批量用上述直接手動輸入便可;

但若遇到要配置 100、1000 這種大批量記憶體,

慢慢輸入不方便,而用 printf 、cout 、Debug.Print 又浪費時間,

此部份如何觀查將於他篇文章再做簡述。

edisonx 發表在 痞客邦 PIXNET 留言(0) 人氣()