2014-12-03 78 views
0

在一個本地函數中,我想計算圖中有多少個節點指向彼此(in-degree),並且它由相鄰列表表示。奇怪的是,當我在這個函數中打印時,我所有的數字都是正確的,但是當我離開這個函數時,我失去了其中的一半。C - 指向int的本地指針丟失了一半大小

VertexType *InDegree(Graph G) 
{ 
    int Size, i; 
    Size = G->GraphSize; // Size is 17 

    VertexType *degree; 

    for (i = 0; i < Size; ++i) 
     degree[ i ] = 0; 

    for (i = 0; i < Size; ++i) 
    { 
     VertexNodePtr P; 
     P = G->Vertices[ i ].AdjList; 

     // A traverse, not relevant to this question 
     while (P != NULL) 
     { 
      ++degree[ P->Vertex ]; 
      P = P->Next; 
     } 
    } 
    // here I can print all the numbers using a 
    // for-loop counting to 17, correctly. 
    // but sizeof() gives me half the length I expect! 
    // which is 8. And out of this function counting to 
    // 17 causes an overflow. 
    return degree; 
} 

回答

3
sizeof

是一個操作符,其不能確定一個動態分配的陣列的大小(或靜態數組衰減到指針)。結果是8,因爲您可能正在使用指針類型(例如VertexType*)計算它,並返回指針的大小(以64字節體系結構中的8字節爲單位)。

忽略sizeof結果在這種特定情況下,在處理數組時,它只能計算靜態(或本地數組)的總字節數。

+0

謝謝,我檢查了它忽略'sizeof',這是正確的。溢出必須是其他地方的錯誤。 – knh170 2014-12-03 15:49:02

+1

'sizeof'是一個運算符,而不是宏。 – Clifford 2014-12-03 15:49:39

2

sizeof(degree)指針的大小不是節點的數量,或者甚至是單個節點的大小。

在生產線:

degree[ i ] = 0; 

您正在訪問一個unitialised指針,然後寫一個值吧! degree必須指出有效之前,你這樣做。代碼很可能會崩潰,肯定是不正確的。

1

的問題是,sizeof(x)得到指針本身(這是8你的情況,因爲你正在編譯64位程序)的大小,並它指向的對象。

這意味着sizeof(T*)是相同的(或者4或在x86/amd64上8),無論T

不幸的是,沒有函數獲得指向的對象的長度,因此您將自己跟蹤該事件。

有一點要注意的是,sizeof(x)得到實際尺寸(以字節爲單位,而不是成員的#)的陣列(不要與指針混合陣列):

int a[10] = 5; 
int* ap = a; 

// outputs `10 * sizeof(int)` --- `4` for most modern architectures 
printf("%zu\n", sizeof(a)); 
// outputs the size of the *pointer* (usually 4 or 8) 
printf("%zu\n", sizeof(ap)); 

應當指出的是,在參數,一個int a[10]聲明僅僅是一個指針:

void printA(int a[10]) { 
    // outputs *SIZE OF POINTER* --- 4 or 8 
    //  --- because `a` is actually just a pointer! 
    printf("%zu\n", sizeof(a)); 
} 

...因此,以下是完全等價(*注意如下):

void printA(int a[10]) {...} 
void printA(int a[]) {...} 
void printA(int* a) {...} 

注:可能有細微的差別,在編譯器可以發出警告時,大小不匹配int a[10]變體;但這只是一個供應商的延伸,就標準而言,它們都是一樣的。