2013-06-27 61 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,你实际上可以通过引用传递并填充被调用的函数。消除冗余大小,重要的是处理内存的麻烦。