Нарушение прав доступа при попытке использовать std :: vectors, созданные путем копирования элементов из массива - PullRequest
0 голосов
/ 28 января 2019

Я работаю над проектом C ++ / CX DirectX, на который ссылается проект UWP.

Следующая функция является частью проекта C ++ / CX и вызывается из проекта UWP в начале,главным образом для создания нескольких сеток.

Все работало нормально, пока я не изменился, поэтому вместо одного _trackMesh это std::vector (_trackMeshes), содержащий несколько сеток.(в основном я хотел разделить сетку с максимальным количеством точек на сетку).

Но когда я пытаюсь разделить массив, содержащий все точки, я получаю нарушение прав доступа после установки localPlayerId, нодо конца.Я понятия не имею, почему.

Любая помощь высоко ценится.

Код:

IAsyncAction^ Track3DControl::InitializeAsync(const Array<TrackPoint>^ trackPoints, const Array<IPlayer^>^ players, int localPlayerId)
{
    _logger->Trace(L"InitializeAsync()");
    _isInitialized = false;

    Utilities::Copy(trackPoints, _trackPoints);

    int pointCount = trackPoints->Length;
    const int maxPointCount = 5000;
    int count = (int)ceil(pointCount / (double)maxPointCount);
    _logger->Error("_trackMeshes count: " + count);

    _trackMeshes = ref new Array<TrackMesh^>(count);
    for (int i = 0; i < count; i++)
    {
        _trackMeshes[i] = ref new TrackMesh(_logger, _d3dDevice, _d3dContext);
    }

    std::vector<task<void>> tasks;
    for (int i = 0; i < count; i++)
    {
        int start = i * maxPointCount;
        int end = (i + 1)*maxPointCount;
        if (end > pointCount)
        {
            end = pointCount;// -1;
        }
        std::vector<TrackPoint> part(end);
        for (size_t j = 0; j < end-start; j++)
        {
            part[j] = _trackPoints[j+ start];
        }
        tasks.push_back(_trackMeshes[i]->InitializeAsync(&part));
    }

    for (auto index = 0u; index < static_cast<unsigned int>(_playerMeshes.size()); ++index)
    {
        tasks.push_back(_playerMeshes.at(index)->InitializeAsync(_playerModel.get()));
    }

    _localPlayerId = localPlayerId;

    return create_async([this, tasks]
    {
        return when_all(tasks.begin(), tasks.end()).then([this]
        {
            _isInitialized = true;

            _logger->Trace(L"Initialized.");
        });
    });
}

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Проблема в том, что вы пытаетесь получить доступ к локальной переменной после ее удаления.Смотрите здесь (другой код удален):

for (int i = 0; i < count; i++)
{
    std::vector<TrackPoint> part(end); // <-- part created here

    tasks.push_back(_trackMeshes[i]->InitializeAsync(&part));

} // <-- part destroyed here

Каждый раз, когда вокруг цикла вы создаете part, передайте его адрес InitializeAsync, а затем удалите его.Какой бы код вы ни выполняли в асинхронной части InitializeAsync, он будет обращаться к удаленной памяти.

0 голосов
/ 31 января 2019

Я заметил, что векторы верны перед отправкой в ​​трек-сетки ( tasks.push_back (_trackMeshes [i] -> InitializeAsync (& part)); ), но они были пустыми к тому времени, когда тактына самом деле начинается.

Итак, я думаю, они почему-то выходят за рамки?

Я сохранил векторы part в переменной-члене ( std :: vector> запчасти ) и как-то это все исправляет.

Если кто-то сможет мне это объяснить, я отмечу это как правильный ответ

...