2012-11-26 169 views
3

我有以下代碼,對於爲什麼出現分段錯誤我有點困惑。C指向數組的指針

typedef struct { 
    int tag; 
    int valid; 
} Row; 

typedef struct { 
    int index; 
    int num_rows; 
    Row **rows; 
} Set; 

/* STRUCT CONSTRUCTORS */ 

// Returns a pointer to a new Sow. 
// all fields of this row are NULL 
Row* new_row() { 
    Row* r = malloc(sizeof(Row)); 
    return r; 
} 

// Returns a pointer to a new Set. 
// the set's index is the given index, and it has an array of 
// rows of the given length. 
Set* new_set(int index, int num_rows, int block_size) { 
    Set* s = malloc(sizeof(Set)); 
    s->index = index; 
    s->num_rows = num_rows; 

    Row* rows[num_rows]; 
    for (int i = 0; i < num_rows; i++) { 
    Row* row_p = new_row(); 
    rows[i] = row_p; 
    } 
    s->rows = rows; 

    return s; 
} 

/* PRINTING */ 

void print_row(Row* row) { 
    printf("<<T: %d, V: %d>>", row->tag, row->valid); 
} 

void print_set(Set* set) { 
    printf("[ INDEX %d :", set->index); 


    for (int i = 0; i < set->num_rows; i++) { 
    Row* row_p = set->rows[i]; 
    print_row(row_p); 
    } 

    printf(" ]\n"); 
} 


int main(int argc, char const *argv[]) { 

    Set* s = new_set(1, 4, 8); 
    print_set(s); 


    return 0; 

} 

基本上一個Set有一個指針指向的秒的陣列。我認爲Row* row_p = set->rows[i];是從一組中獲得排的正確方法,但我必須錯過一些東西。

回答

4

您分配的Row*小號

Row* rows[num_rows]; 
    for (int i = 0; i < num_rows; i++) { 
    Row* row_p = new_row(); 
    rows[i] = row_p; 
    } 
    s->rows = rows; 

本地陣列,讓rows指針Set點到的。函數返回後,本地數組不再存在,因此s->rows是一個懸掛指針。在函數返回後仍然有效的內存必須分配給malloc(或其一個表兄弟)。

1

s->rows在功能new_set(),這意味着s->rows分配局部變量rows的地址是一個dangling pointernew_set()回報。動態分配的Row*陣列糾正:

s->rows = malloc(num_rows * sizeof(Row*)); 
if (s->rows) 
{ 
    /* for loop as is. */ 
} 

記住s->rows,以及作爲其元素,必須free() d。