2013-06-27 56 views
1

我創建了一個函數,返回一個錯誤代碼(ErrCode枚舉)並傳遞兩個輸出參數。但是當我打印函數的結果時,我沒有在數組中得到正確的值。作爲輸出參數在c + +

// .. some codes here .. 
ErrCode err; 
short lstCnt; 
short lstArr[] = {}; 
err = getTrimmedList(lstArr, &lstCnt); 

// list returned array (for comparison) 
for (int i=0; i<lstCnt; ++i) 
printf("lstArr[%3d] = %d", i, lstArr[i]); 
// .. some codes here .. 

getTrimmedList功能是這樣的:

ErrCode getTrimmedList(short* vList, short* vCnt) 
{ 
    short cnt; 
    ErrCode err = foo.getListCount(FOO_TYPE_1, &cnt); 
    if (NoError!=err) return err; 

    short* list = new short [cnt]; 

    short total = 0; 
    for (short i=0; i<cnt; ++i) 
    { 
    FooBar bar = foo.getEntryByIndex(FOO_TYPE_1, i); 

    if (bar.isDeleted) continue; 

    list[total] = i; 
    ++total; 
    } 

    *vCnt = total; 
    //vList = (short*)realloc(index, sizeof(short)*total); 
    vList = (short*)malloc(sizeof(short)*total); 
    memcpy(vList, list, sizeof(short)*total) 

    // list returned array (for comparison) 
    for (int i=0; i<lstCnt; ++i) 
    printf("lstArr[%3d] = %d", i, lstArr[i]); 

    return NoError; 
} 

其中:

  • foo是保持FooBar對象
  • foo.getListCount()陣列的對象返回與類型對象的數量FOO_TYPE_1
  • FOO_TYPE_1是我們要採取的對象/列表的類型
  • foo.getEntryByIndex()返回一個類型FOO_TYPE_1
  • bar.isDeletediFooBar對象如果bar被視爲「已刪除」或不
告訴標誌

我的錯誤是什麼?

編輯:

對不起,我抄錯了線。我在上面評論它,並把正確的路線。

編輯2

我沒有過的foobar回報控制。它們的所有函數返回值都是ErrCode,輸出通過參數傳遞。

+0

這不是C++代碼,也就是C代碼。對於C++,您應該使用['std :: vector'](http://en.cppreference.com/w/cpp/container/vector)。 –

+0

和'int main'。 – chris

回答

1

幾個問題之前,我可以回答你的帖子...

哪裏是「指數」中定義: vList = (short*)realloc(index, sizeof(short)*total);

你與泄漏相關的記憶: short* list = new short [cnt];

是它可能你不小心混淆了內存分配中的指針?無論如何,這裏是一個例子。你有很多問題,但你應該能夠用它作爲指導來回答這個問題,因爲它最初被問到。

工作示例:

#include "stdio.h" 
#include "stdlib.h" 
#include "string.h" 

int getTrimmedList(short** vList, short* vCnt); 

int main() 
{ 
    // .. some codes here .. 
    int err; 
    short lstCnt; 
    short *lstArr = NULL; 
    err = getTrimmedList(&lstArr, &lstCnt); 

    // list returned array (for comparison) 
    for (int i=0; i<lstCnt; ++i) 
    printf("lstArr[%3d] = %d\n", i, lstArr[i]); 
    // .. some codes here .. 

    return 0; 
} 

int getTrimmedList(short** vList, short* vCnt) 
{ 
    short cnt = 5; 
    short* list = new short [cnt]; 
    short* newList = NULL; 

    short total = 0; 
    list[0] = 0; 
    list[1] = 3; 
    list[2] = 4; 
    list[3] = 6; 
    total = 4; 

    *vCnt = total; 
    newList = (short*)realloc(*vList, sizeof(short)*total); 
    if (newList) { 
    memcpy(newList, list, sizeof(short)*total); 
    *vList = newList; 
    } else { 
    memcpy(*vList, list, sizeof(short)*total); 
    } 

    delete list; 

    return 0; 
} 
+0

我相信作者的意圖是將vList作爲out參數返回。不知道索引來自哪裏,但是基於其他Foo *接口,我假設一些魔法被遺漏。 – crowder

+0

我只是想澄清,因爲「魔術」可能是他糟糕的一天的原因。 ;) – Zak

+0

沒問題! :) – crowder

0

您應該使用std :: vector代替原始c風格的數組,並且在此處使用「&」而不是「*」來傳遞引用。現在,你沒有正確地設置你的輸出參數(如果你想返回一個新的數組給你的調用者,那麼指向數組的指針看起來像「short ** arr_ptr」而不是「short * arr_ptr」 - 這個API是。非常容易出錯,但是,如你發現了)

你getTrimmedList功能,因此,應該有這樣的簽名:

ErrCode getTrimmedList(std::vector<short> &lst); 

現在你不再需要你的「計數」參數,以及 - C++的標準容器都有查詢內容大小的方法。

C++ 11還可以讓您更加具體地瞭解整數的空間要求,所以如果您要查找16位「short」,您可能需要int16_t。

ErrCode getTrimmedList(std::vector<int16_t> &lst); 

這也可能是合理的,以避免要求你的來電者創造「出來的」陣列,因爲我們在這裏使用更智能的容器:

std::vector<int16_t> getTrimmedList(); // not a reference in the return here 

在這種風格,我們可能會管理錯誤但是,使用異常而不是返回代碼,所以關於您的界面的其他內容也會發生變化,這很可能。

1

你有嚴重的問題。

對於初學者來說,當你使用它時,你的函數只有一個輸出參數:vCnt。 vList僅用作局部變量。

realloc被稱爲一些index,我們無所謂,不太好。它必須是來自malloc()或realloc()的東西。

只要退出getTrimmedList,vList中分配的內存就會泄漏。

如果您調用該函數,則將本地lstArr數組作爲第一個參數傳遞,而不用於任何內容。然後將原始的,未改變的數組打印到cnt中的邊界,而它仍然有0個大小 - 行爲未定義。

即使您設法通過ref傳遞該數組,您也無法將其重新分配給不同的值--C風格的數組無法做到這一點。

你最好使用std :: vector,你實際上可以通過引用傳遞並填充被調用的函數。消除冗餘大小,重要的是處理內存的麻煩。