2013-06-27 2 views
1

Я создал функцию, которая возвращает код ошибки (ErrCode enum) и передает два выходных параметра. Но когда я печатаю результат функции, я не получаю правильные значения в массиве.Array as out in 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() возвращает i й FooBar объект типа FOO_TYPE_1
  • bar.isDeleted является флаг, который говорит, если bar рассматривается как «удалено» или нет

Какая у меня ошибка?

Edit:

К сожалению, я скопировал неправильную линию. Я прокомментировал это выше и поставлю правильную строку.

Edit 2

не имеет контроля над возвратов foo и bar. Все их функции возвращают 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-стиля, а также использовать ссылку «&» вместо «*» здесь. Прямо сейчас вы неправильно устанавливаете свой параметр out (указатель на массив будет выглядеть как «short ** arr_ptr», а не «short * arr_ptr», если вы хотите вернуть новый массив вашему вызывающему абоненту - этот API . сильно подвержены ошибкам, однако, как вы выяснить)

Ваша функция getTrimmedList, следовательно, должны иметь эту подпись:

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

Теперь вы больше не нужны ваши «сосчитать» параметров, а также - Стандартные контейнеры C++ имеют способы запроса размера их содержимого.

C++ 11 также позволяет уточнить требования к пространству для int, поэтому, если вы ищете 16-разрядный «короткий», вы, вероятно, хотите получить int16_t.

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

Он также может быть разумным, чтобы избежать требующих вашего абонента, чтобы создать «из» массива, так как мы используем более интеллектуальные контейнеры здесь:

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

В этом стиле, мы, скорее всего, управлять ошибками однако использование исключений, а не возвратных кодов, тем не менее, скорее всего, будут развиваться и другие аспекты вашего интерфейса.

1

У вас есть серьезные проблемы.

Для начала ваша функция имеет только один параметр вывода, который вы используете: vCnt. vВы можете использовать только локальную переменную.

realloc вызывается с некоторыми index, о которых мы ничего не знаем, вряд ли хорошо. Это должно быть что-то от malloc() или realloc().

Выделенная память в vList просочилась, как только вы выходите из getTrimmedList.

Где вы вызываете функцию, вы передаете локальный массив lstArr в качестве первого аргумента, который не используется ни для чего. Затем напечатайте исходный неизменный массив до границ в cnt, в то время как он имеет размер 0 - поведение не определено.

Даже если вам удалось передать этот массив по ссылке ref, вы не сможете переназначить его на другое значение - массивы C-стиля не могут этого сделать.

Вам лучше использовать std :: vector, который вы можете фактически передать по ссылке и заполнить вызываемую функцию. устраняя избыточный размер и, главное, беспорядок с обработкой памяти.

 Смежные вопросы

  • Нет связанных вопросов^_^