2014-11-03 5 views
1

Я работаю над программой на языке C, которая содержит массив указателей на структуры. Сначала структура выглядит следующим образом:возвращающий указатель на массив указателей структуры

typedef struct 
{ 
    int ID; 
    char Name [20]; 
} rec; 

Тогда у меня есть функция, которая создает 1 из этих структур:

struct rec* addEntry(){ 
    rec *temp; 
    temp = malloc(sizeof(rec)); 
    printf("Please give me an ID number\n"); 
    scanf("%d", &temp->ID); 

    printf("Now give me a name, maximum size for this is 20 characters\n"); 
    scanf("%s", &temp->Name); 
    return temp; 
} 

Теперь эта функция работает нормально, это создает структуру и возвращает указатель в стороне, что структура Я тогда другая функция, которая создает массив указателей и заполняет его с указателями в стороне:

структур
struct rec* returnPointerToPointerArray() 
{ 
    rec *pointerArray[2]; 
    pointerArray[0] = addEntry(); 
    pointerArray[1] = addEntry(); 
    printf("ID in main : %d\n", pointerArray[0]->ID); 
    printf("Name in main : %s\n", pointerArray[0]->Name); 
    printf("ID in main : %d\n", pointerArray[1]->ID); 
    printf("Name in main : %s\n", pointerArray[1]->Name); 
    pointerArray = malloc(sizeof(rec*)*2); 
    return pointerArray; 
} 

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

Однако теперь мне нужно создать malloc для этого указателяArray и вернуть указатель на этот массив указателей, и именно там я застрял.

таНос линия дает мне ошибку:

error: incompatible types when assigning to type 'struct rec *[(sizetype)(size)]' from type 'void *' 

Теперь уточнить, я не могу использовать связанный список, я должен использовать массив указателей вместо этого. Чтобы добавить в моем главном цикле у меня есть другая ошибка в следующем кусочке кода:

rec *pointerArray[2]; 
pointerArray = returnPointerToPointerArray(2); 
printf("ID in main : %d\n", pointerArray[0]->ID); 
printf("Name in main : %s\n", pointerArray[0]->Name); 

Это дает мне следующее сообщение об ошибке:

error: incompatible types when assigning to type 'struct rec *[2]' from type 'struct rec *' 

Любая помощь более чем приветствуется.

Спасибо заранее, Ильва

+0

'pointerArray = таНос (SizeOf (прн *) * 2);' не будет работать и в любом случае слишком поздно для того, что вы намеревались с тех пор, как вы уже пытались запастись в него. 'pointerArray' - это массив автоматического хранения, а не указатель, поэтому вы не можете его malloc. –

+0

Но если бы я вернул указатель на этот массив, тогда массив не исчезнет, ​​так как он объявлен локально? – Ylva

+0

Вы создали указатели на структуру в обеих функциях, не инициализируя их точкой в ​​любом месте перед их использованием. Я написал пример ниже (были ошибки при первом написании, они были протестированы сейчас) – ryyker

ответ

1

Этот код не имеет смысла:

struct rec* returnPointerToPointerArray() 
{ 
    rec *pointerArray[2]; 
    pointerArray[0] = addEntry(); 
    pointerArray[1] = addEntry(); 
    ... 
    pointerArray = malloc(sizeof(rec*)*2); 
    return pointerArray; 
} 

вы определяете стек массив указателей и назначение кучи адресов для struct rec объектов к ним, а затем пытается назначить кучу на основе массив из двух указателей на адрес стека. Он никогда не будет компилироваться.

Поскольку ваша функция предназначена для возврата указателя на объект типа rec (который будет первой из двух структур в массиве, который я предполагаю), вы должны сначала выделить в куче пространство для двух указателей (и, таким образом, использовать двойной указатель), а затем заполнить его/вернуть его:

struct rec** returnPointerToPointerArray() 
{ 
    rec **pointerArray; 
    pointerArray = malloc(sizeof(rec*)*2); // Allocates 2 pointers 
    pointerArray[0] = addEntry(); 
    pointerArray[1] = addEntry(); 
    ... 
    return pointerArray; 
} 

Live Example

вы также должны освободить выделенную память, когда вы закончите.

+2

Наконец-то это больше похоже. –

+0

Спасибо, не знал, что вам нужно сделать двойной указатель здесь. – Ylva

+0

'struct rec' и' rec' - это разные типы, и вы возвращаете указатель на ** один ** из записей. –

0

две проблемы я определил:

Во-первых, вы возвращаетесь, прежде чем скопировать результат в pointerArray.

pointerArray = malloc(sizeof(rec*)*2); 
return pointerArray; 

мое предложение

struct rec** returnPointerToPointerArray() 
{ 
    rec *pointerArray[2]; 
    pointerArray[0] = addEntry(); 
    pointerArray[1] = addEntry(); 
    printf("ID in main : %d\n", pointerArray[0]->ID); 
    printf("Name in main : %s\n", pointerArray[0]->Name); 
    printf("ID in main : %d\n", pointerArray[1]->ID); 
    printf("Name in main : %s\n", pointerArray[1]->Name); 
    rec **pointerArray2 = malloc(sizeof pointerArray); 
    pointerArray2[0] = pointerArray[0]; 
    pointerArray2[1] = pointerArray[1]; 
    return pointerArray2; 
} 

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

Во-вторых,

rec *pointerArray[2]; 

представляет собой массив указателей. способ заявить об этом просто:

rec **pointerArray; 

Кстати,

pointerArray = returnPointerToPointerArray(2); 

эта линия должна сделать использование и декларацией несоответствия.

UPDATE:

нашли ошибку в моем ответе. вы возвращаете массив указателей.

+0

будет rec * pointerArray; не просто создать указатель на тип rec? а не быть массивом указателей на тип rec? – Ylva

+0

@Ylva не понимает, о чем вы беспокоитесь. указатель и массив идентичны в системе ввода. 'rec * pointerArray;' - указатель, указывающий на какой-то адрес. разыменовывая его как массив с помощью 'pointerArray [1]' или так. – HuStmpHrrr

+0

pointerArray = returnPointerToPointerArray (2); действительно не будет работать, должен быть pointerArray = returnPointerToPointerArray(); – Ylva

0
typedef struct 
{ 
    int ID; 
    char Name [20]; 
} rec; 

struct rec* returnPointerToPointerArray() 
{ 
    rec *pointerArray[2]; 
    pointerArray[0] = addEntry(); 
    pointerArray[1] = addEntry(); 
    ... 
    return pointerArray; 
} 

Тип возврата неверен по двум причинам. Функция возвращает rec *, в то время как объявляется как возвращаемый указатель на неопределенный struct rec *. Тип struct rec отличается от typedef rec!

Во-вторых, вы должны вернуть указатель на указатель на номер rec. Когда вы возвращаете массив, имя массива преобразуется в указатель на его первый элемент, который сам по себе является указателем.

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

Вам нужно первую выделить динамическую память для массива, заполнить массив, а затем вернуть его:

rec** returnPointerToPointerArray() 
{ 
    rec **pA = malloc (2 * sizeof *pA); 
    if (pA) { 
    pA[0] = addEntry(); 
    pA[1] = addEntry(); 
    if (pA[0]) { 
     printf("ID in main : %d\n", pA[0]->ID); 
     printf("Name in main : %s\n", pA[0]->Name); 
    } 
    if (pA[1]) { 
     printf("ID in main : %d\n", pA[1]->ID); 
     printf("Name in main : %s\n", pA[1]->Name); 
    } 
    } 
    return pA; 
} 

Та же проблема здесь:

rec *pointerArray[2]; 
pointerArray = returnPointerToPointerArray(2); 
printf("ID in main : %d\n", pointerArray[0]->ID); 
printf("Name in main : %s\n", pointerArray[0]->Name); 

Вы не можете назначить новый значение для массива. Вам нужно определить pointerArray как указатель на указатель:

rec **pointerArray; 
pointerArray = returnPointerToPointerArray(/*2*/); 
Смежные вопросы