1

我创建了一个返回错误代码(ErrCode枚举)并传递两个输出参数的函数。但是当我打印函数的结果时,我没有在数组中得到正确的值。

// .. 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()返回类型为ith的FooBar对象FOO_TYPE_1
  • bar.isDeleted是一个标志,指示是否bar被视为“已删除”

我的错误是什么?

编辑:

抱歉,我复制了错误的行。我在上面发表了评论并输入了正确的行。

编辑 2

我无法控制fooand的回报bar。它们的所有函数返回都是ErrCode,输出是通过参数传递的。

4

3 回答 3

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;
}
于 2013-06-27T02:07:35.837 回答
1

你有严重的问题。

对于初学者,您的函数在使用时只有一个输出参数:vCnt。vList 您仅用作局部变量。

realloc 与一些index我们一无所知的调用,不太可能好。它一定是从 malloc() 或 realloc() 得到的。

一旦退出 getTrimmedList,vList 中分配的内存就会泄露。

在调用函数的地方,您将本地 lstArr 数组作为第一个参数传递,该参数不用于任何操作。然后将原始的、未更改的数组打印到 cnt 中的边界,而它的大小仍然为 0 - 行为未定义。

即使您设法通过 ref 传递该数组,您也无法将其重新分配给不同的值——C 风格的数组无法做到这一点。

您最好使用 std::vector ,您实际上可以通过引用传递并填写被调用的函数。消除冗余大小,重要的是消除内存处理的混乱。

于 2013-06-27T02:08:18.683 回答
0

您应该使用 std::vector 代替原始 c 样式数组,并在此处使用“&”而不是“*”进行引用传递。现在,您没有正确设置 out 参数(如果您想向调用者返回一个新数组,则指向数组的指针看起来像“short **arr_ptr”而不是“short *arr_ptr”——这个 API 是但是,正如您所发现的那样,非常容易出错。)

因此,您的 getTrimmedList 函数应具有以下签名:

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

现在您也不再需要“计数”参数了——C++ 的标准容器都有查询其内容大小的方法。

C++11 还允许您更具体地了解整数的空间要求,因此如果您正在寻找 16 位“短”,您可能需要 int16_t。

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

避免要求调用者创建“out”数组也可能是合理的,因为我们在这里使用了更智能的容器:

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

但是,在这种风格中,我们可能会使用异常而不是返回码来管理错误,因此关于您的界面的其他事情也很可能会发展。

于 2013-06-27T01:56:24.153 回答