Случайная инициализация структуры - PullRequest
0 голосов
/ 03 марта 2020

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

#include <cmath>
#include <ctime>

struct Point{
    double x;
    double y;
    double z;
};
struct Triangle{
    Point* a;
    Point* b;
    Point* c;
};
int main() {
    Triangle t1;
    srand(time(0));
        t1.a->x=10.0*(rand()/RAND_MAX)-5; //this line gives Segmentation fault
        t1.a->y=10.0*(rand()/RAND_MAX)-5;
        t1.a->z=10.0*(rand()/RAND_MAX)-5;
        t1.b->x=10.0*(rand()/RAND_MAX)-5;
        t1.b->y=10.0*(rand()/RAND_MAX)-5;
        t1.b->z=10.0*(rand()/RAND_MAX)-5;
        t1.c->x=10.0*(rand()/RAND_MAX)-5;
        t1.c->y=10.0*(rand()/RAND_MAX)-5;
        t1.c->z=10.0*(rand()/RAND_MAX)-5;
}

Ответы [ 2 ]

8 голосов
/ 03 марта 2020

Вы разыменовываете неинициализированные указатели с неопределенным поведением.

Нет смысла использовать здесь указатели - просто используйте Point s в качестве членов.
Это имеет несколько преимуществ:

  • Вам не нужно беспокоиться о «правиле чего угодно»; это просто работает
  • Вы можете написать менее утомительный код бухгалтерского учета, так что у вас больше времени подумать о менее скучных вещах
  • Это более чем вероятно, будет более эффективным (динамически c выделение медленное)

Затем добавьте пару функций, чтобы вам не нужно было так много копировать и вставлять:

struct Point{
    double x;
    double y;
    double z;
};

struct Triangle{
    Point a;
    Point b;
    Point c;
};

double random_value()
{
    return (10.0*rand())/RAND_MAX - 5;
}

Point random_point()
{
    return { random_value(), random_value(), random_value() };
}

Triangle random_triangle()
{
    return { random_point(), random_point(), random_point() };
}

int main() {
    srand(time(0));
    Triangle t1 = random_triangle();
}
1 голос
/ 03 марта 2020

Этот код содержит UB!

Как упоминалось в комментариях, потому что код, который вы написали, запрашивает значение, на которое указывает каждый указатель в неинициализированной структуре Triangle t1, сгенерированном компилятором код, который не определен стандарт. Это известно как НЕОПРЕДЕЛЕННОЕ ПОВЕДЕНИЕ , потому что нет никакого разумного значения, чтобы дать указатели по умолчанию. Я полагаю, что при использовании конфигурации отладки компилятор по умолчанию инициализирует указанные указатели значением 0, что является недоступным адресом.

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

Еще одна вещь, на которую стоит обратить внимание, это то, что вы, похоже, не слишком задумывались над своим вопросом. В будущем я бы попробовал больше протестировать проблемы, которые у вас есть, попытаться решить их самостоятельно, и, в крайнем случае, задать здесь вопрос о переполнении стека. Задавая вопрос, предоставьте как можно больше информации, особенно информацию, которую вы нашли, пытаясь решить проблему самостоятельно. Спасибо;)

...