Структура, содержащая массив структуры, не может быть выделена значениями из списка того же типа - PullRequest
1 голос
/ 01 мая 2019

Моя проблема заключается в следующем: у меня есть структура с именем Environment, содержащая список Obstacle структур. Я не могу выделить environment.obstacles из существующего списка Obstacle, созданного вручную в коде.

У меня есть следующие определения:

struct PointGPS {
    double longitude;
    double latitude;
} typedef PointGPS;

struct Obstacle {
    int id;
    PointGPS position;
    double radius;
} typedef Obstacle;

struct Environment {
    Obstacle *obstacles;
    PointGPS destination;
} typedef Environment;

И я использую следующие функции для создания экземпляров моих значений:

PointGPS createPoint(double longitude, double latitude) {
    PointGPS point;
    point.latitude = latitude;
    point.longitude = longitude;
    return point;
}

Obstacle createObstacle(int id, double radius, PointGPS position) {
    Obstacle obstacle;
    obstacle.id = id;
    obstacle.radius = radius;
    obstacle.position = position;
    return obstacle;
}

Environment createEnvironment(PointGPS destination, Obstacle *obstacles) {
    Environment environment;
    environment.destination = destination;
    environment.obstacles = obstacles;
    return environment;
}

В моей функции main я создаю список препятствий:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))

int main() {
    PointGPS pointGps1 = createPoint(49.202538, 6.918930);
    PointGPS pointGps2 = createPoint(49.202650, 6.925839);
    PointGPS destination = createPoint(49.202660, 6.925849);
    Obstacle obstacle1 = createObstacle(1, 10, pointGps1);
    Obstacle obstacle2 = createObstacle(2, 30, pointGps2);
    Obstacle *obstacles[2];
    obstacles[0] = &obstacle1;
    obstacles[1] = &obstacle2;
    // environment is global
    environment = createEnvironment(destination, *obstacles);
    // The two following methods allow me to print the id of the first element
    printf("%d\n", environment.obstacles->id);
    printf("%d\n", environment.obstacles[0].id);
    // But I cant access to the values -for exemple the id field- of the following obstacles
    printf("%d\n", environment.obstacles[1].id);
}

Я хочу передать этот список моим environment. Но он не выделяет или указывает на правильные значения. Тестирование id некоторых препятствий в environment.obstacles всегда возвращает некоторые случайные целочисленные значения из памяти.

Я попробовал следующие попытки:

1)

// environment is global
environment = createEnvironment(destination, *obstacles);

2)

environment.obstacles = (Obstacle *)malloc(sizeof(Obstacle *) * NELEMS(obstacles));
environment.obstacles[0] = *obstacles[0];
environment.obstacles[1] = *obstacles[1];

3)

environment.obstacles = (Obstacle *)malloc(sizeof(Obstacle *) * NELEMS(obstacles));
environment.obstacles[0] = createObstacle(obstacles[0]->id, obstacles[0]->radius, createPoint(obstacles[0]->position.longitude, obstacles[0]->position.latitude));
environment.obstacles[1] = createObstacle(obstacles[1]->id, obstacles[1]->radius, 
createPoint(obstacles[1]->position.longitude, obstacles[1]->position.latitude));

Все эти попытки потерпели неудачу, возвращая значения, подобные -2144113376, и даже не создавая массив длины = 2 в моей переменной environment.

Я почти уверен, что упускаю что-то очевидное, поскольку у меня нет опыта в этом языке, но я не могу понять это. Как я мог продолжить?

ОБНОВЛЕНИЕ 1 :

Этот синтаксис позволил мне получить доступ к первому препятствию, используя метод № 1:

printf("%d\n", environment.obstacles->id)

Но я не могу получить доступ ко второму препятствию. Выполнение printf("%d\n", environment.obstacles[1]->id); возвращает эту ошибку:

Member reference type 'Obstacle' (aka 'struct Obstacle') is not a pointer, did you mean to use '.'?

И выполнение printf("%d\n", environment.obstacles[1].id); по-прежнему возвращает случайные значения.

ОБНОВЛЕНИЕ 2 :

По запросу я отредактировал структуры, функции и основные.

ОБНОВЛЕНИЕ 3 :

Вот тестируемый код, делающий то, что делается в моем посте. https://onlinegdb.com/S1342WPsN Если я запускаю код на своем компьютере, у меня все еще остаются случайные значения, как описано при попытке доступа к полям, следующим за первым. Но если я запускаю код внутри веб-сайта (см. Ссылку), он, кажется, дает правильное значение.

Ответы [ 2 ]

2 голосов
/ 01 мая 2019

Существует путаница между массивами и указателями. obstacles в вашей функции main представляет собой массив указателей на Obstacle структуры. Возможно, вы захотите определить массив Obstacle структур, инициализированных с копиями obstacle1 и obstacle2, и передать его в createEnvironment. Передача массива в качестве аргумента эффективно передает указатель на его первый элемент.

Вот модифицированная версия:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))

int main() {
    PointGPS pointGps1 = createPoint(49.202538, 6.918930);
    PointGPS pointGps2 = createPoint(49.202650, 6.925839);
    PointGPS destination = createPoint(49.202660, 6.925849);
    Obstacle obstacle1 = createObstacle(1, 10, pointGps1);
    Obstacle obstacle2 = createObstacle(2, 30, pointGps2);
    Obstacle obstacles[2];
    obstacles[0] = obstacle1;
    obstacles[1] = obstacle2;
    // environment is global
    environment = createEnvironment(destination, obstacles);
    // The two following methods allow me to print the id of the first element
    printf("%d\n", environment.obstacles->id);
    printf("%d\n", environment.obstacles[0].id);
    // This one should print the id of the second element
    printf("%d\n", environment.obstacles[1].id);
    return 0;
}

Обратите внимание, что ваши определения tyedef не являются идиоматическими в C. Ключевое слово typedef обычно стоит первым:

typedef struct PointGPS {
    double longitude;
    double latitude;
} PointGPS;
0 голосов
/ 02 мая 2019

Просто чтобы добавить картинки к проблеме, это то, что было определено в вашем коде, (простите мой UML.)

The data types.

То, что вы сделали, создало это.

The data.

В частности, *obstacles совпадает с obstacles[0] = &obstacle1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...