C и доступ к элементу динамической структуры - PullRequest
2 голосов
/ 02 апреля 2011

У меня есть такая сложная структура, вещь:

#include <stdlib.h>

typedef struct {
    int x;
    int y;
} SUB;

typedef struct {
    int a;
    SUB *z;
} STRUCT;

#define NUM  5

int main(void)
{
    STRUCT *example;
    int i;

    example = malloc(sizeof(STRUCT));

    example->z = malloc(NUM * sizeof(SUB));

    for(i = 0; i < NUM; ++i) {
        /* how do I access variable in certain struct of array of z's */
    }

    return 0;
}

example - это динамически распределенная структура, а z внутри example - это динамически распределенный массив SUB структур.

Как получить доступ к определенной переменной в определенном элементе структуры z?

Я пытался что-то вроде этого: example->z[i].x но, похоже, не работает.

В данный момент я использую этот потертый вид решения:

SUB *ptr = example->z;
int i;

for(i = 0; i < amount_of_z_structs; ++i) {
    /* do something with  'ptr->x' and 'ptr->y' */
    ptr += sizeof(SUB);
}

Ответы [ 6 ]

1 голос
/ 02 апреля 2011

Ваша проблема не там, где вы говорите.Ваш код после публикации выдает ошибку компиляции:

error: request for member ‘z’ in something not a structure or union

в строке

example.z = malloc(sizeof(STRUCT));

, потому что вы хотели написать example->z, поскольку example - указатель на STRUCTа не STRUCT.

С этого момента вы можете получить доступ к example->z[i].x в точности так, как вы сказали.Этот синтаксис всегда был в порядке.

Например:

/* your declarations here */

example = malloc(sizeof(STRUCT));
example->z = malloc(NUM * sizeof(SUB));

for(i = 0; i < NUM; ++i) {
    example->z[i].x = i;
    example->z[i].y = -i;
    printf("%d %d\n", example->z[i].x, example->z[i].y);
}

/* output:
0 0
1 -1
2 -2
3 -3
4 -4
*/
0 голосов
/ 02 апреля 2011
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>

#define NUM 5

typedef struct
{
    int x;
    int y;
}SUB;

typedef struct
{
    int a;
    SUB* z;
}STRUCT;

void main(void)
{
    clrscr();
    printf("Sample problem..\n\n");

    STRUCT* example;
    int i;

    example = (STRUCT*)malloc(sizeof(STRUCT));
    example->z = (SUB*)malloc(NUM * sizeof(SUB));

    for(i = 0; i < NUM; i++)
    {
        example->z[i].x = i +1;
        example->z[i].y = (example->z[i].x)+1;
        printf("i = %d: x:%d y:%d\n", i, example->z[i].x, example->z[i].y);
    }
}
0 голосов
/ 02 апреля 2011

В «потертом обходном пути» вы написали:

SUB *ptr = example->z;
int i;

for(i = 0; i < amount_of_z_structs; ++i) {
    /* do something with  'ptr->x' and 'ptr->y' */
    ptr += sizeof(SUB);
}

Проблема здесь в том, что C масштабирует указатели по размеру объекта, на который указывает, поэтому, когда вы добавляете 1 к указателю SUBзначение увеличивается на sizeof(SUB).Итак, вам просто нужно:

SUB *ptr = example->z;
int i;

for (i = 0; i < NUM; ++i) {
    ptr->x = ptr->y = 0;
    ptr++;
}

Конечно, как уже говорили другие, вы также можете сделать (в предположении C99):

for (int i = 0; i < NUM; ++i)
    example->z[i].x = example->z[i].y = 0;
0 голосов
/ 02 апреля 2011

Прежде всего, ваш второй malloc неверен; example - это указатель, так что:

example.z = malloc(NUM * sizeof(SUB));

должно быть так:

example->z = malloc(NUM * sizeof(SUB));

Тогда в своем цикле вы можете сказать что-то вроде этого:

example->z[i].x = i;
example->z[i].y = i;

Вам также нужно иметь это в верхней части вашего файла:

#include <stdlib.h>
0 голосов
/ 02 апреля 2011

Попробуйте это:

int my_x = example[3].z[2].x;
  • Приведенный выше код сначала получит доступ к примеру [3] (четвертый элемент массива примеров).
  • Как только вы получите этот конкретный элемент, к его содержимому можно автоматически получить доступ так же, как и к обычным объектам.
  • Затем вы получите доступ к z [2] из этого элемента.Обратите внимание, что example[3] является элементом, поэтому вы можете использовать . для доступа к его элементам;если это массив, вы можете обращаться к нему как к массиву.
  • Так что до сих пор example[3].z[2] является одним элементом массива SUB внутри одного элемента* Массив 1018 *.
  • Теперь вы можете просто получить доступ к элементу x, используя способ, показанный выше.

typedef struct {
    int x;
    int y;
} SUB;

typedef struct {
    int a;
    SUB *z;
} STRUCT;

STRUCT *example;

int main() {
    example = malloc(sizeof(STRUCT)*10); //array of 10;
    int i=0,j=0;
    for (;i<10;i++){
        example[i].a = i;
        example[i].z = malloc(sizeof(SUB)*5);
        for (j=0; j<5; j++)
            example[i].z[j].x = example[i].z[j].y = j;
    }
    //access example[3] and access z[2] inside it. And finally access 'x'
    int my_x = example[3].z[2].x;
    printf("%d",my_x);

    for (i=0;i<10;i++){
        printf("%d |\n",example[i].a);
        //example[i].z = malloc(sizeof(SUB)*5);
        for (j=0; j<5; j++)
            printf("%d %d\n",example[i].z[j].x,example[i].z[j].y);
        free(example[i].z);
    }
    free(example);
}

0 голосов
/ 02 апреля 2011

Когда у вас есть указатели, указывающие на указатели, вы часто сталкиваетесь с проблемами приоритета.Я не могу вспомнить, если это один, но вы можете попробовать (example->b)[i].x.

...