2015-05-02 40 views
3

我目前正在學習C並且必須編寫一個「動態數組」。複製組件的struct刪除同一個結構的另一個組件

在所提供的頭文件,該結構的DynArray聲明爲

struct DynamicArray 
{ 
    unsigned int size; 
    unsigned int capacity; 

    int *data; 
}; 

我已經實現了大部分功能在dyn_array方案,該方案得到了空函數。
我的difficutly位於函數dn_append(DynamicArray * a,int elem)。我給出的唯一描述是

// ===================================================================================== 
//   Name: dn_append 
// Description: Append an element. 
// 
// Parameters: a - the array 
//    elem - the new value 
//  Returns: non-zero, if the array was successfully extended 
// ===================================================================================== 

我們有一個makefile來編譯這個和一些測試用例。在其中一個測試程序中,初始化新DynArray,然後附加幾個值:

int 
main (int argc, char *argv[]) 
{ 
    DynamicArray *a1; 
    int      i; 

    a1 = dn_new (5); 

    dn_append (a1, 5); 
    dn_append (a1, 7); 
    dn_append (a1, 8); 
    dn_append (a1, 11); 
    dn_append (a1, 13); 
    dn_append (a1, 15); 

    dn_set (a1, 2, 9); 

    for (i = 0; i < dn_size (a1); i += 1) 
    { 
     printf ("%d\n", dn_get (a1, i)); 
    } 

    dn_destory (a1); 

    return 0; 
} 

它會因分段錯誤而中止。
我的(錯誤)實現如下。外部的其他情況完全搞砸了,因爲調試讓我瘋狂。 (請注意,我解釋代碼樣品之後有問題的線路。)

int 
dn_append (DynamicArray *a, int elem) 
{ 
    printf("\n\nAppend:\n"); 
    if (a->size >= a->capacity) { 
     printf("Array too small"); 
     int *dataPtr = realloc(a->data, 2*a->capacity); 

     if (dataPtr != NULL) { 
      a->capacity *= 2; 
      a->data = dataPtr; 
      a->data[a->size] = elem; 
      a->size++; 
     } 
     else { 
       return 0; 
     } 
    } 
    else { 
     int *dataPtr; 
     dataPtr = a->data; 

     printf("Size: %d, Capacity: %d\n", a->size, a->capacity); 
     int sizeN = a->size; 
     printf("Size: %d, Capacity: %d\n", a->size, a->capacity); 

     //int offset = sizeN; 
     int *temp; 
     temp = dataPtr;// + offset; 
     //dataPtr[offset] = elem; 
     //printf("Data at %d is %d, should be %d\n", offset, *(a->data), elem); 

     a->size++; 
    } 

    return 1; 
} 

有問題的線是在所述外其他情況下,在中間:

printf("Size: %d, Capacity: %d\n", a->size, a->capacity); 
    int sizeN = a->size; 
    printf("Size: %d, Capacity: %d\n", a->size, a->capacity); 

當運行該程序,這些行打印出來

Size: 0, Capacity: 5 
Size: 0, Capacity: 0 

我甚至不碰capacity -component的結構,而是將其設置爲0,從而徹底,F ***以外s上行下面的程序。

評論行int sizeN = a->size;後,capacity是應該保留的權利。這種或那種方式需要閱讀size

那麼,爲什麼它會改變那個組件呢?


一些額外的相關信息:

DynamicArray* 
dn_new (unsigned int capacity) 
{ 
    if (capacity > 0) { 
     int *dataPtr = malloc(capacity*sizeof(int)); 

     if (dataPtr != NULL) { 
      struct DynamicArray array = { 0, capacity, dataPtr }; 
      return &array; 
     } 
     else { 
      return NULL; 
     } 
    } 
    else { 
     return NULL; 
    } 
} 
+0

這是一種寫得很好的家庭作業問題,我會花時間閱讀和回答。 +1。 – ace

+1

請顯示您的分配器函數,並嘗試在'valgrind'和/或調試器中運行您的代碼。 – Mat

+0

dn_new是什麼樣的? – nneonneo

回答

3

在你dn_new()您有:

if (dataPtr != NULL) { 
    struct DynamicArray array = { 0, capacity, dataPtr }; 
    return &array; 
} 

這裏,array是一個局部變量;它在返回後將超出範圍。你應該在堆中分配內存爲:

struct DynamicArray *array = malloc(sizeof *array); 
array->size = 0; 
array->capacity = capacity; 
array->data = dataPtr; 
return array; 

要記住,這free()內存在你的析構函數(dn_destroy())。

+0

非常感謝!我曾嘗試過,但編譯器說'標量初始化程序中的多餘元素',所以我試圖做一個解決方法。顯然我做了一些不同的事情... – J0hj0h

+0

是的,這是這裏的問題。通過返回一個局部變量,它將被未來的函數調用破壞。 – nneonneo

2

看來你混了,你如何解釋你的尺寸和容量。您可以像使用它們一樣計數元素的數量,但是將它們分配爲(realloc)作爲字節數。你的代碼更改爲以下:

int *dataPtr = realloc(a->data, 2*a->capacity*sizeof(a->data[0])); 
+0

我改變了(sizeof(int),因爲我們只允許int值),但上述問題仍然存在。不過謝謝你的提示! – J0hj0h

相關問題