Список инициализаторов C++ для пользовательских классов, работающих ненормально

Может ли кто-нибудь помочь мне понять, что не так с приведенным ниже кодом?

Я использую С++20

Я инициализирую вектор вектора класса «Интервал», но он инициализируется нулями.

#include <bits/stdc++.h>
using namespace std;

class Interval {
public:
    int start;
    int end;

    Interval() {}

    Interval(int _start, int _end) {
        start = _start;
        end = _end;
    }
};

vector<Interval> solve(vector<vector<Interval>> schedule) {
    vector<Interval> allSchedule;

    for(auto it : schedule) {
        for(auto it1 : it) {
            allSchedule.push_back(it1);
        }
    }

    auto comparator = [](Interval a, Interval b) {
        return a.start > b.start;
    };
    sort(allSchedule.begin(), allSchedule.end(), comparator);

    return allSchedule;
}

int main() {
    vector<vector<Interval>> schedule;
    schedule.push_back({new Interval(1,2), new Interval(5,6)});
    schedule.push_back({new Interval(1,3), new Interval(4,10)});
    vector<Interval> allSchedules = solve(schedule);
    for(auto it : allSchedules) {
        cout << it.start << " -> " << it.end << endl;
    }
    return 0;
}

Получение результата ниже (неожиданно)

1 -> 2
1 -> 3
0 -> 0
0 -> 0

И чего вы ожидаете?

3CxEZiVlQ 19.07.2024 19:58

Не могу повторить ваш результат. Я понимаю fatal error: 'bits/stdc++.h' file not found.

3CxEZiVlQ 19.07.2024 20:00
{new Interval(1,2), new Interval(5,6)} — здесь вы вызываете std::vector(begin, end) constructor, что приводит к неопределенному поведению, поскольку new Interval(1,2), new Interval(5,6) не являются началом и концом массива. Кажется, у вас есть опыт работы с Java или C#. vector<Interval> не является вектором указателей и new вам не нужен.
3CxEZiVlQ 19.07.2024 20:05

Обязательно не рискуйте выстрелить себе в ногу #include <bits/stdc++.h> post.

user4581301 19.07.2024 20:43

Полезный инструмент: дезинфицирующие средства. Вот ваш код, скомпилированный с большим количеством предупреждений и включенными базовыми дезинфицирующими средствами: godbolt.org/z/fxWWrj91P . Предупреждения не могут выявить эту проблему, но очиститель адресов довольно быстро определяет, что вы на самом деле не использовали итераторы, когда обнаруживает, что программа выходит за пределы допустимой памяти. Выяснение того, что на самом деле произошло в этом случае, требует опыта, который вы приобретете в течение следующих нескольких месяцев (и лет).

user4581301 19.07.2024 20:48
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
99
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий
vector<vector<Interval>> schedule;
schedule.push_back({new Interval(1,2), new Interval(5,6)});

это очень странная ошибка, потому что vector имеет конструктор, который можно использовать для его инициализации двумя указателями (итераторами) на другой контейнер, например:

Interval intervals[2];
vector<vector<Interval>> schedule;
schedule.push_back(std::vector<Interval>{ &(intervals[0]), &(intervals[2])});

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

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

vector<vector<Interval>> schedule;
schedule.push_back({Interval(1,2), Interval(5,6)});
schedule.push_back({Interval(1,3), Interval(4,10)});

{new Interval(1,2), new Interval(5,6)} — здесь вы вызываете конструктор std::vector(const Interval* begin, const Interval* end), который приводит к неопределенному поведению, поскольку new Interval(1,2), new Interval(5,6) не являются началом и концом массива.

Кажется, у вас есть опыт работы с Java или C#: vector<Interval> не является вектором указателей, и new вам не нужен.

Заменять

schedule.push_back({new Interval(1,2), new Interval(5,6)});
schedule.push_back({new Interval(1,3), new Interval(4,10)});

с

schedule.push_back({{1, 2}, {5, 6}});
schedule.push_back({{1, 3}, {4, 10}});
//    inner vector ^^^^^^^^^^^^^^^^^ 
//inner vec elements^^^^^^  ^^^^^^^ - intervals

Выход:

5 -> 6
4 -> 10
1 -> 2
1 -> 3

Interval может быть агрегатом, для него не нужны определяемые пользователем конструкторы Interval() и Interval(int, int).

class Interval {
 public:
  int start;
  int end;
};

Лучше, если solve и comparator получают свои аргументы по ссылкам const (еще один пример возможного использования Java или C#).

vector<Interval> solve(const vector<vector<Interval>>& schedule);
auto comparator = [](const Interval& a, const Interval& b)

Другие вопросы по теме