Вам нужно передать указатель на указатель, т.е. int **newlist
. В частности, newlist передается в вашу функцию по значению, поэтому newlist в main
и внутри вашей функции - это две совершенно разные переменные.
В тесте также есть ошибка для четных чисел:
#include <stdio.h>
#include <stdlib.h>
int takeEven(int *nums, int numelements, int **newlist) {
int *list = malloc(numelements * sizeof **newlist);
*newlist = list; // this modifies the value of newlist in main
int i, found = 0;
for(i = 0; i < numelements; ++i, nums++) {
if ((*nums % 2) == 0) {
*(list++) = *nums;
found++;
}
}
list -= found;
printf("First number found %d\n", *list); // <= works correctly
return found;
}
int main()
{
int nums[] = {1,2,3,4,5};
int *evenNums;
int i;
int n = takeEven(nums, sizeof(nums) / sizeof(*nums), &evenNums);
for (i = 0; i < n; ++i) {
printf("%d\n", *(evenNums++));
}
return 0;
}
Вы также можете взглянуть на этот вопрос из C-FAQ, в котором также рассматривается ваша проблема:
В: У меня есть функция, которая принимает и должна инициализировать указатель:
void f(int *ip)
{
static int dummy = 5;
ip = &dummy;
}
Но когда я называю это так:
int *ip;
f(ip);
указатель в вызывающей стороне остается неизменным.
A: Вы уверены, что функция инициализировала то, что, как вы думали, она сделала? Помните, что аргументы в C передаются по значению. В приведенном выше коде вызываемая функция изменяет только переданную копию указателя. Чтобы заставить его работать так, как вы ожидаете, одним из исправлений является передача адреса указателя (функция заканчивает тем, что принимает указатель на указатель; в этом случае мы по сути имитируем передачу по ссылке):
void f(ipp)
int **ipp;
{
static int dummy = 5;
*ipp = &dummy;
}
...
int *ip;
f(&ip);
Другое решение состоит в том, чтобы функция возвращала указатель:
int *f()
{
static int dummy = 5;
return &dummy;
}
...
int *ip = f();
См. Также вопросы 4,9 и 4,11 .