2016-06-10 107 views
0

我已經寫了這個功能在一個UINT32陣列的奇數或偶數索引計算值的平均值:分段錯誤將值分配給當解引用雙指針

void average_uint32_t(uint32_t * begin, uint32_t *end, 
      uint8_t skip, uint32_t **result){ 

    //safety check 
    if(begin == end || begin > end) { 
     printf("begin and end pointer does not belong to an array\n"); 
     *result = 0; //set pointer to null 
     return; 
    } 

    uint64_t sum = 0; 
    uint32_t count = 0; 

    while(begin <= end) { 
     sum += *begin; 
     count++; 
     printf("count=%d,value=%d,sum=%lu\n", count, *begin, sum); 
     begin += skip; 
    } 

    **result = ((uint32_t)(sum/count)); //segmentation fault here 
    printf("result=%d\n", **result); 
} 

我測試像這樣的功能:

//BUFF_SIZE = 8 
uint32_t buffer[BUFF_SIZE] = {0,1,2,3,4,5,6,7}; 

uint32_t * average = 0; //memory to get result back 

//even indices => 0,2,4,6 
average_uint32_t(buffer, buffer + BUFF_SIZE - 1, 2, &average); 
printf("average of even elements = %d\n", *average); 

//odd indices => 1,3,5,7 
average_uint32_t(buffer + 1, buffer + BUFF_SIZE, 2, &average); 
printf("average of odd elements = %d\n", *average); 

但是,當結果的分配達到平均值時(正如我在功能代碼中所評論的),程序遇到了分段錯誤。這裏是輸出:

count=1,value=0,sum=0 
count=2,value=2,sum=2 
count=3,value=4,sum=6 
count=4,value=6,sum=12 
Signal: SIGSEGV (Segmentation fault) 

我在做什麼錯?我猜一般函數的單個指針可以解決這個問題嗎?但爲什麼雙指針不起作用?

回答

1

這是因爲uint32_t *average沒有指向有效的內存區域。

試試這個:

uint32_t uiAverage = 0; 
uint32_t *average = &uiAverage; 

更好更多的將是使用double,而不是uint_32_t因爲平均可以是一個浮點數。所以,如果你打算使用雙,那麼你還需要行

**result = ((uint32_t)(sum/count));
更改爲
**result = ((double)sum/(double)count));

+0

感謝解決了這個問題,好點,但爲什麼它沒有指向一個有效的內存地址在開始? –

+0

@SaeidYazdani:'uint32_t * average'是一個指針,uint32_t * average = 0;'只是表示'uint32_t * average = NULL;'。所以,如果你理解初始化一個指向NULL的含義,那麼很明顯,在大多數平臺上'0'最有可能是受限制的內存位置。 – sameerkn

1

您定義average作爲一個空指針。它是Undefined Behavior來取消引用空指針,並且在大多數Unix版本中,它會給出分段違規。

,如果你想使用雙指針,平均必須點到一個現有的變量,您必須使用一個指針指向一個真實變量,或。