libsaria: Resizing a vector invalidates pointers
I was keeping a vector of objects, and then pass pointers to these objects around everywhere. HOWEVER, when vectors are resized they allocate new memory and copy things over invalidating iterators and pointers to the original objects. This can cause memory corruption issues when I try to use a pointer to an object that no longer exists. The simple solution? Allocate tracks dynamically and then store the pointer in the library path. Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
This commit is contained in:
parent
c094f9791f
commit
05bbad5444
|
@ -19,10 +19,11 @@ namespace libsaria
|
|||
bool visible;
|
||||
unsigned int id;
|
||||
string path;
|
||||
vector<Track> tracks;
|
||||
vector<Track *> tracks;
|
||||
};
|
||||
|
||||
void init();
|
||||
void quit();
|
||||
void add_path(string);
|
||||
void delete_path(Path *);
|
||||
void update_path(Path *);
|
||||
|
|
|
@ -66,7 +66,7 @@ static void do_task(IdleTask *task)
|
|||
|
||||
static void queue_task(IdleTask *task)
|
||||
{
|
||||
idle_queue.push_front(task);
|
||||
idle_queue.push_back(task);
|
||||
queued += 1.0;
|
||||
libsaria::notify(IDLE_ADD, NULL);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ static string id_to_filename(unsigned int id)
|
|||
static void do_save_path(ofstream &stream, void *data)
|
||||
{
|
||||
libsaria::library::Path *path = (libsaria::library::Path *)data;
|
||||
list<libsaria::Track>::iterator it;
|
||||
println("Saving library path: %d", path->id);
|
||||
|
||||
stream << LIBRARY_CURRENT_VERSION << "\n";
|
||||
|
@ -37,7 +36,7 @@ static void do_save_path(ofstream &stream, void *data)
|
|||
stream << path->tracks.size() << "\n";
|
||||
|
||||
for (unsigned int i = 0; i < path->tracks.size(); i++)
|
||||
path->tracks[i].save(&stream);
|
||||
path->tracks[i]->save(&stream);
|
||||
}
|
||||
|
||||
void libsaria::library::save_path(libsaria::library::Path *path)
|
||||
|
@ -76,8 +75,8 @@ void read_path(ifstream &stream)
|
|||
|
||||
path_ptr = push_path(path);
|
||||
for (unsigned int i = 0; i < size; i++) {
|
||||
path_ptr->tracks.push_back(libsaria::Track(stream, path_ptr, version));
|
||||
track = &path_ptr->tracks.back();
|
||||
track = new libsaria::Track(stream, path_ptr, version);
|
||||
path_ptr->tracks.push_back(track);
|
||||
if ((*track)[TRACK_ID] != i)
|
||||
(*track)[TRACK_ID] = i;
|
||||
}
|
||||
|
|
|
@ -29,12 +29,12 @@ libsaria::library::Path *push_path(libsaria::library::Path &path)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
static void hide_track(libsaria::Track &track)
|
||||
static void hide_track(libsaria::Track *track)
|
||||
{
|
||||
if (track[TRACK_BANNED])
|
||||
libsaria::ban::get_banned_plist()->remove_track(&track);
|
||||
if ((*track)[TRACK_BANNED])
|
||||
libsaria::ban::get_banned_plist()->remove_track(track);
|
||||
else
|
||||
lib_playlist.remove_track(&track);
|
||||
lib_playlist.remove_track(track);
|
||||
}
|
||||
|
||||
void pop_path(libsaria::library::Path *path)
|
||||
|
@ -74,13 +74,10 @@ namespace libsaria
|
|||
|
||||
void library::delete_path(Path *path)
|
||||
{
|
||||
list<Track>::iterator it;
|
||||
list<Path>::iterator p_it;
|
||||
|
||||
remove_file(path);
|
||||
for (unsigned int i = 0; i < path->tracks.size(); i++) {
|
||||
hide_track(path->tracks[i]);
|
||||
libsaria::deck::track_removed(&path->tracks[i]);
|
||||
libsaria::deck::track_removed(path->tracks[i]);
|
||||
}
|
||||
pop_path(path);
|
||||
}
|
||||
|
@ -101,7 +98,7 @@ namespace libsaria
|
|||
{
|
||||
for (unsigned int i = 0; i < path->tracks.size(); i++) {
|
||||
hide_track(path->tracks[i]);
|
||||
libsaria::deck::track_removed(&path->tracks[i]);
|
||||
libsaria::deck::track_removed(path->tracks[i]);
|
||||
}
|
||||
path->visible = false;
|
||||
save_path(path);
|
||||
|
@ -114,7 +111,7 @@ namespace libsaria
|
|||
Track *track;
|
||||
|
||||
for (unsigned int i = 0; i < path->tracks.size(); i++) {
|
||||
track = &path->tracks[i];
|
||||
track = path->tracks[i];
|
||||
if ((*track)[TRACK_BANNED])
|
||||
ban.push_back(track);
|
||||
else
|
||||
|
@ -134,7 +131,7 @@ namespace libsaria
|
|||
return NULL;
|
||||
if (trackid >= path_list[libid].tracks.size())
|
||||
return NULL;
|
||||
return &path_list[libid].tracks[trackid];
|
||||
return path_list[libid].tracks[trackid];
|
||||
}
|
||||
|
||||
void library::set_random(bool random)
|
||||
|
@ -158,4 +155,14 @@ namespace libsaria
|
|||
idle::schedule(restore_current);
|
||||
}
|
||||
|
||||
void library::quit()
|
||||
{
|
||||
struct libsaria::library::Path *path;
|
||||
for (unsigned int i = 0; i < path_list.size(); i++) {
|
||||
path = &path_list[i];
|
||||
for (unsigned int j = 0; j < path->tracks.size(); j++)
|
||||
delete path->tracks[j];
|
||||
}
|
||||
}
|
||||
|
||||
}; /* namespace: libsaria */
|
||||
|
|
|
@ -18,7 +18,7 @@ static void validate_path(void *d)
|
|||
|
||||
path = (struct libsaria::library::Path *)d;
|
||||
while (i < path->tracks.size()) {
|
||||
track = &path->tracks[i];
|
||||
track = path->tracks[i];
|
||||
if (!libsaria::exists((*track)[TRACK_FILEPATH])) {
|
||||
println("Reaping: " + (*track)[TRACK_FILEPATH]);
|
||||
lib_playlist.remove_track(track);
|
||||
|
@ -54,7 +54,7 @@ static void setup_scan_data(struct ScanData *scan, list<string> &files)
|
|||
static bool find_file(libsaria::library::Path *path, string &file)
|
||||
{
|
||||
for (unsigned int i = 0; i < path->tracks.size(); i++) {
|
||||
if (path->tracks[i][TRACK_FILEPATH] == file)
|
||||
if ((*path->tracks[i])[TRACK_FILEPATH] == file)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -65,6 +65,7 @@ static void scan_path(void *data)
|
|||
struct ScanData *scan = (struct ScanData *)data;
|
||||
list<string>::iterator it;
|
||||
libsaria::library::Path *path = scan->path;
|
||||
libsaria::Track *track;
|
||||
|
||||
for (it = scan->files.begin(); it != scan->files.end(); it++) {
|
||||
/*
|
||||
|
@ -77,8 +78,9 @@ static void scan_path(void *data)
|
|||
continue;
|
||||
|
||||
try {
|
||||
path->tracks.push_back(libsaria::Track(*it, path));
|
||||
lib_playlist.push_back(&path->tracks.back());
|
||||
track = new libsaria::Track(*it, path);
|
||||
path->tracks.push_back(track);
|
||||
lib_playlist.push_back(track);
|
||||
} catch (string message) {
|
||||
println(message);
|
||||
}
|
||||
|
@ -88,12 +90,10 @@ static void scan_path(void *data)
|
|||
delete scan;
|
||||
}
|
||||
|
||||
|
||||
static void update_path(void *d)
|
||||
{
|
||||
struct libsaria::library::Path *path;
|
||||
list<string> file_list;
|
||||
list<string>::iterator it;
|
||||
unsigned int i;
|
||||
struct ScanData *data;
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ namespace libsaria
|
|||
{
|
||||
println("Quitting libsaria");
|
||||
app::close_pipe();
|
||||
library::quit();
|
||||
audio::quit();
|
||||
print_format_stats();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue