C++ Сброс ядра при очистки памяти

92
21 марта 2022, 21:50

есть 2 двумерного динамического массива один типа char другой типа sf::Sprite(из SFML)

при очистке массива типа char происходит сброс ядра

вот код: World.h:

#ifndef WORLD_H
#define WORLD_H
#include <SFML/Graphics.hpp>
typedef unsigned short int _usi;
class World : public sf::Transformable, public sf::Drawable
{
public:
    World();
    void draw(sf::RenderTarget& target, sf::RenderStates states) const;
    void generateWorld();
    ~World();
private:
    sf::Texture textureTile;
    //level one
    const _usi worldLevelOneHeight = 10;
    const _usi worldLevelOneWidth = 20;
    char** worldLevelOne;
    sf::Sprite** worldSpriteLevelOne;
};
#endif // WORLD_H

World.cpp:

#include "world.h"
#include <iostream>
World::World()
{
    textureTile.loadFromFile("media/Tiles.png");
    worldLevelOne = new char*[worldLevelOneHeight];
    worldSpriteLevelOne = new sf::Sprite*[worldLevelOneHeight];
    for(_usi h = 0; h < worldLevelOneHeight; ++h)
    {
        worldSpriteLevelOne[h] = new sf::Sprite[worldLevelOneWidth];
        worldLevelOne[h] = new char[worldLevelOneWidth];
    }
}
void World::generateWorld()
{
    worldLevelOne[0] = "                    ";
    worldLevelOne[1] = "                    ";
    worldLevelOne[2] = "                    ";
    worldLevelOne[3] = "                    ";
    worldLevelOne[4] = "                    ";
    worldLevelOne[5] = "                    ";
    worldLevelOne[6] = "====================";
    worldLevelOne[7] = "                    ";
    worldLevelOne[8] = "                    ";
    worldLevelOne[9] = "                    ";
    worldLevelOne[10] ="                    ";
    for(_usi h = 0; h < worldLevelOneHeight; ++h)
    {
        for(_usi w = 0; w < worldLevelOneWidth; ++w)
        {
            //set textures
            if(worldLevelOne[h][w] != ' ')
            {
                worldSpriteLevelOne[h][w].setTexture(textureTile);
                if(worldLevelOne[h][w] == '=') worldSpriteLevelOne[h][w].setTextureRect(sf::IntRect(0,0,73,73));
                else  worldSpriteLevelOne[h][w].setTextureRect(sf::IntRect(73,0,73,73));
                worldSpriteLevelOne[h][w].setPosition(w*73, h*73);
            }
        }
    }
}
void World::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    states.transform *= getTransform();
    for(_usi h = 0; h < worldLevelOneHeight; ++h)
    {
        for(_usi w = 0; w < worldLevelOneWidth; ++w)
        {
            target.draw(worldSpriteLevelOne[h][w], states);
        }
    }
}
World::~World()
{
    for(_usi h = 0; h < worldLevelOneHeight; ++h)
    {
        delete[] worldLevelOne[h]; //ТУТ ОШИБКА
        delete[] worldSpriteLevelOne[h];
    }
    delete[] worldSpriteLevelOne;
    delete[] worldLevelOne;
}

тут создается World:

#include "game.h"
#include "world.h"
//Конструктор игры, присвоение данных
Game::Game(unsigned short int windowWidth, unsigned short int windowHeight, bool isFullScreen, unsigned short int fps)
{
    this->windowWidth = windowWidth;
    this->windowHeight = windowHeight;
    this->isFullScreen = isFullScreen;
    this->fps = fps;
}
//функция основнова цикла игры
void Game::open()
{
    //создание мира
    World world;
    world.generateWorld();
    //FullScreen или нет
    if(isFullScreen)
        window.create(sf::VideoMode(windowWidth, windowHeight), "Platformer", sf::Style::Fullscreen);
    else
        window.create(sf::VideoMode(windowWidth, windowHeight), "Platformer");
    window.setFramerateLimit(fps); //ставим FPS
    //цикл игры
    while(window.isOpen())
    {
        while(window.pollEvent(ev))
        {
            if(ev.type == sf::Event::Closed) window.close();
        }
        window.clear(sf::Color(100,255,50));
        window.draw(world);
        window.display();
    }
}

при чем массив типа sf::Sprite очищается нормально, а char со сбросом ядра

Answer 1

Очевидно выделенные на строке worldLevelOne[h] = new char[worldLevelOneWidth]; указатели затираются указателями на строковые литералы в worldLevelOne[0] = " "; (это вообще-то невалидная операция). Вместо char** worldLevelOne; используйте std::vector размером worldLevelOneHeight x worldLevelOneWidth

READ ALSO
Состояние формата ввода/вывода по умолчанию

Состояние формата ввода/вывода по умолчанию

При копировании состояния формата ввода, обнаружил, что по умолчанию оно не нулевоеРешил провести тест: обнулить и смотреть что получается:

84
Не работают вектора C++

Не работают вектора C++

Я работаю над 2D игрой на SFMl c++но думаю это не принципиально

72
Как добавить элементы в двусвязный список?

Как добавить элементы в двусвязный список?

Помогите пожалуйста дописать программуНужно написать процедуру, которая, получив в качестве параметра указатель на один из элементов двусвязного...

415
Двойное нажатие ЛКМ

Двойное нажатие ЛКМ

Я хочу сделать программу, которая при одном клике делает второй(нужно для копирования от 1 клика)Но,что я не пробовал, всё-равно выполняется...

81