SDL2 2.0.22 strange behavior

Hi !
A few days ago, I tried the latest release of SDL2 (wanted to try new features, SDL_RenderGeometryRaw looks awesome!)

I’m testing it in a tiny video game i’m developping and I started to saw some strange crash, mostly at the end of the program (on SDL_Quit and TTF_Quit)

At the beginning, I was sure I messed up something somewhere; I thought I did probably a mistake a few months ago and the update just highlight it (like bad use of new and delete, memory management etc … you know what im talking about)

But after more deep testing, i’m in big trouble; I managed to code something that work on older SDL2 version (tested in 2.0.15) but not in the latest build (2.0.22)

After initalising everything, the code create a dynamic array of 1000 Struct, every struct contening a vector of shared_ptr, fill with 1000 Member.
Every Member has a string; (PS: Doing this is ok, isn’t it? I did this a lot but now I’m wondering?)

after allocating the memory, the program can crash if you click on the windows (SDL_MOUSEBUTTONDOWN). (If it did not crash, retry, It will happen)
** If you enter a key, the program will always exists without any problem.**
There is the code:

// Crash using SDL 2.0.22 and SDL_TTF 2.20.0 x64 on VS2019 (c++17, using Windows 10)
// does not crash using older version of SDL2 (testing with 2.0.15)

#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <iostream>
#include <vector>

struct Member{
	Member(){
		someStr = "test";
	}
	std::string someStr;
};

struct Struct{
	Struct(){
		// adding 1000 Member into the shared_ptr vector of Struct
		// each Member contening a simple string
		for(int i = 0; i < 1000; i++){
			members.push_back(std::make_shared<Member>(std::move(Member())));
		}
	}
	std::vector<std::shared_ptr<Member> > members;
};


int main(int argc, char *argv[])
{
	// initialize everything
	if(SDL_Init(SDL_INIT_EVERYTHING) != 0)
		return -1;

	SDL_Window *window;
	window = SDL_CreateWindow("test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 
							  SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_MAXIMIZED | SDL_WINDOW_RESIZABLE);

	SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
	if(renderer == nullptr)
		return -1;

	if(TTF_Init() == -1){
		return -1;
	}

	bool end = false;
	// creation a dynamic array of 1000 Struct
	Struct *structArray = new Struct[1000];
	std::cout << "memory allocated; mouse click for crash or press a key to exit the program normally \n"; 
	SDL_Event eventSDL;
	while(!end){
		while(SDL_PollEvent(&eventSDL)){
			// does crash half the time (more structArray is big, more often it will occur)
			if(eventSDL.type == SDL_MOUSEBUTTONDOWN){
				end = true;
			}
			// does NOT crash
			if(eventSDL.type == SDL_KEYDOWN){
				end = true;
			}
		}
	}
	std::cout << "freeing memory ...\n";
	delete[] structArray;

	std::cout << "quitting SDL / TTF ...\n";
	SDL_Quit();
	TTF_Quit(); // <- can crash here only if SDL_MOUSEBUTTONDOWN was activated

	std::cout << "exit\n";
	return 0;
}

Am I doing something wrong ? Is it bad to have a vector of shared ptr in a member of a dynamic array ?
Thanks in advance !

This exact code causes a crash for you?


Not a problem but just want to let you know that

members.push_back(std::make_shared<Member>(std::move(Member())))

can be written as

members.push_back(std::make_shared<Member>())

because make_shared calls the constructor internally.

The arguments that you pass to make_shared are the arguments that you want to pass to the constructor. In your code you created a temporary Member object and let make_shared pass it on to the move constructor which was a bit unnecessary.

Thank you for your advice, I was not aware of that!
but no, the program does not crash at this line (and yes, this exact piece of code crashs on my PCs using SDL 2.0.22); it can crashs at the very end (SDL_Quit() if (and only) if I clicked on the window to exit the infinite loop.
Quitting the infinite loop using key does not crash the app.

Maybe TTF_Quit() has to be called before SDL_Quit()?

Switching SDL_Quit() and TTF_Quit() does produce the same problem at the same place (My compiler says the crash come from SDL2.dll (Access Violation));
In fact, I can’t understand why leaving the loop with SDL_MOUSEBUTTONDOWN crashs the program, while doing the same thing with SDL_KEYDOWN does not.

I tested it on 2 differents computers, and the code crashed in the same way as I described earlier. You can try it yourself, install the latest SDL2 build, SDL TTF too, and you are good to go. (the crashs does not appear with earlier version, 2.0.15 or 2.0.18 do not have this problem)

I think there is some memory corruption somewhere, and I do not think the code I posted as anything to do with that - but I can be wrong

I tested the example code, but without using SDL_ttf, and got the same segfault problem on SDL_Quit when clicking with the mouse. However, adding a SDL_Destroy_Window call before SDL_Quit solved the problem.