Я создал функцию, которая возвращает код ошибки (ErrCode
enum) и передать два выходных параметра. Но когда я печатаю результат функции, я не получаю правильные значения в массиве.
// .. 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
считается удаленным или нетВ чем моя ошибка?
Редактировать:
Извините, я скопировал не ту строку. Я прокомментировал это выше и поставил правильную строку.
Редактировать 2
Я не могу контролировать возврат foo
а также bar
, Все их функции возвращаются ErrCode
и выходы передаются через параметр.
Пара вопросов, прежде чем я смогу ответить на ваш пост …
Где «индекс» определен в:
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;
}
У вас серьезные проблемы.
Для начала, ваша функция имеет только один выходной параметр, который вы используете: vCnt.
vList вы используете как локальную переменную.
realloc вызывается с некоторыми index
что мы ничего не знаем, скорее всего, не хорошо. Это должно быть что-то полученное из malloc () или realloc ().
Выделенная память в vList просочится, как только вы выйдете из getTrimmedList.
Когда вы вызываете функцию, вы передаете локальный массив lstArr в качестве первого аргумента, который ни для чего не используется. Затем выведите исходный неизмененный массив до границ в cnt, пока он по-прежнему имеет нулевой размер — поведение не определено.
Даже если вам удалось передать этот массив по ссылке, вы не могли переназначить его на другое значение — массивы в стиле C не могут этого сделать.
Вам лучше использовать std :: vector, который вы можете фактически передать по ссылке и заполнить вызываемую функцию. устранение избыточного размера и, что важно, путаницы с обработкой памяти.
Вы должны использовать std :: vector вместо необработанных массивов в стиле c и передавать по ссылке, используя «&»вместо» * «здесь. Прямо сейчас вы неправильно устанавливаете свой параметр out (указатель на массив будет выглядеть как» short ** arr_ptr «, а не» short * arr_ptr «, если вы хотите вернуть новый массив для вашего абонента — однако, как вы выяснили, этот API очень подвержен ошибкам.)
Поэтому ваша функция getTrimmedList должна иметь следующую подпись:
ErrCode getTrimmedList(std::vector<short> &lst);
Теперь вам больше не нужны ваши параметры «count», так как все стандартные контейнеры C ++ имеют возможность запрашивать размер их содержимого.
C ++ 11 также позволяет вам более точно определить требования к пространству для целых, поэтому, если вы ищете 16-битный «short», вам, вероятно, понадобится int16_t.
ErrCode getTrimmedList(std::vector<int16_t> &lst);
Также может быть разумно избегать требования вашего вызывающего к созданию массива «out», так как здесь мы используем более умные контейнеры:
std::vector<int16_t> getTrimmedList(); // not a reference in the return here
В этом стиле мы, скорее всего, будем обрабатывать ошибки, используя исключения, а не коды возврата, однако, скорее всего, будут развиваться и другие аспекты вашего интерфейса.