Ошибка сегментации во время удаления []

Я создаю игру, и мне нужно хранить в динамическом массиве игрока каждый раз, когда он создается. Я создал небольшой фрагмент кода, чтобы попробовать это, и я получаю segmentation fault, когда пытаюсь delete стол вставить третьего игрока. Я просто не могу понять, почему это происходит: файл header:

    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    class Player

{

    private:
        string PlayerName;
        int PlayerScore;
    public:
        Player();       
        Player(string name, int s);     
        ~Player() {};       
        string getPlayerName()  {return PlayerName;}
        int getPlayerScore() {return PlayerScore;}
        void setPlayerName(string name){PlayerName = name;}
        void setPlayerScore(int score){PlayerScore = score;}
};

class Game
{

    private:
        Player NewPlayer;
        int NPlayers;
        Player* PlayerList;
        //vector <Player> PlayerList2;
    
        
    public:
        Game();
        ~Game();
        void setNewPlayer(string, int); 
        void resizePlayerList();
        void PrintList();   
};

class файл:

#include <iostream>
#include <string>
#include <cstring>
#include <memory>
#include "I.h"

using namespace std;


    
Player::Player()
{
    PlayerName = "";
    PlayerScore = 0;
}

Player::Player(string name, int s)
{
    PlayerName = name;
    PlayerScore = s;
}       


Game::Game() 
{
    NPlayers = 0;
    PlayerList = NULL;
};
Game::~Game() {};

void Game::setNewPlayer(string str, int scr)
{
    NewPlayer = Player(str, scr);   
    resizePlayerList(); 
    PrintList();        
}


void Game::resizePlayerList() {
   
    if(NewPlayer.getPlayerName() != "No Name")
    {
            int newSize = NPlayers +1;
            
            Player* newArr = NULL;
            newArr = new Player[newSize];           
            memcpy( newArr, PlayerList, NPlayers * sizeof(Player) );            
            NPlayers = newSize;         
            delete [] PlayerList;           
            PlayerList = newArr;            
            PlayerList[NPlayers-1] = NewPlayer;
    } 
   
}


void Game::PrintList()
{
    Player player;
    //cout << NPlayers << endl;
    for(int i= 0; i < NPlayers; i++)
    {
        player = PlayerList[i];     
        cout << player.getPlayerName() << " " <<  player.getPlayerScore() << endl;  
    }

}

main:

#include <iostream>
#include <string>
#include "I.h"

using namespace std;

int main()
{
    Game NewGame;
    NewGame.setNewPlayer("Peter",20);
    NewGame.setNewPlayer("Someone Someone",30);
    NewGame.setNewPlayer("Someone else",40);
    return 0;
}

В современном C++ вы должны использовать контейнеры и интеллектуальные указатели, а не пытаться управлять этим самостоятельно (потому что это сложно, и вы будете делать ошибки... как вы сделали здесь... используя memcpy на объекте, который не может быть memcpy' г).

Eljay 09.04.2022 16:16

«Мне нужно сохранить игрока в динамическом массиве» -> std::vector

463035818_is_not_a_number 09.04.2022 16:21

если вы вручную управляете памятью, вам нужно прочитать это: stackoverflow.com/questions/4172722/что такое правило трех‌​e, но вам действительно не следует делать это вручную

463035818_is_not_a_number 09.04.2022 16:22
std::vector<Player> playerList; то изменение размера так же тривиально, как playerList.push_back(NewPlayer);
AndersK 09.04.2022 16:27
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
3
4
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема вытекает отсюда:

memcpy(newArr, PlayerList, NPlayers * sizeof(Player));

Таким образом вы копируете классы не можешь, если только они не являются Тривиально копируемый (изначально было сказано ПОД, но, как указывает Yksisarvinen в комментариях, memcpy не является таким ограничительным). Вы можете исправить это, используя вместо этого цикл для копирования данных:

for (int i = 0; i < NPlayers; ++i) {
    newArr[i] = std::move(PlayerList[i]);
}

Однако лучший вариант — использовать std::vector<Player>, тогда вся функция изменения размера может быть упрощена до:

void Game::resizePlayerList() {
    if (NewPlayer.getPlayerName() != "No Name") {
        PlayerList.push_back(std::move(NewPlayer));
    }
}

Или функция <algorithm>std::move вместо цикла.

aschepler 09.04.2022 16:30

@aschepler, честно говоря, даже не знал, что это такое. Это полезно знать для дальнейшего использования :)

ChrisMM 09.04.2022 16:33

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