c++ - Why am I getting heap corrpution when I'm not using new or delete? -
tl;dr: remember std::vector needs move info around when grows, invalidates pointers still have floating around.
i've googled around problem bit, , seems every case came across question of calling delete on same pointer twice. i'm writing little programme , i'm getting heap corruption, thing doing heap allocation c++ standard library. have hunch i'm leaking reference local variable or done wrong polymorphism, can't figure out.
#include <iostream> #include <fstream> #include <sstream> #include <string> #include <vector> using namespace std; struct project; struct solution; struct line { string command; vector<string> params; void print(ostream &os) { os << command << ": "; (string s : params) os << s << ' '; os << endl; } }; struct properties { vector<string> includes; vector<string> libpaths; vector<string> libs; vector<string> sources; vector<string> headers; vector<project *> depends; string folder; string name; string type; }; struct project : properties { project() { built = false; } bool built; void build() { if (built) return; built = true; (project *p : depends) p->build(); cout << "building project: " << name << endl; } }; struct solution : properties { public: project *getproject(const string &name) { (project &p : projects) { if (p.name == name) homecoming &p; } // no project such name -- create project p; cout << &p << endl; p.name = name; projects.push_back(p); cout << "created project: " << name << endl; homecoming getproject(name); } private: vector<project> projects; }; line parseline(const string &strline) { istringstream stream(strline); line line; stream >> line.command; while (stream.good()) { string tok; stream >> tok; if (tok.length() > 0) line.params.push_back(tok); } homecoming line; } template <typename t> vector<t> concat(const vector<t> &a, const vector<t> &b) { vector<t> vec; (t obj : a) vec.push_back(obj); (t obj : b) vec.push_back(obj); homecoming vec; } template <typename t> void printvector(ostream os, vector<t> v) { (t obj : v) os << obj; os << endl; } int main(int argc, char *argv[]) { solution solution; properties *properties = &solution; ifstream stream("testproj.txt"); project p[100]; // no error here.... string linestr; (int linenum = 1; getline(stream, linestr); linenum++) { line line = parseline(linestr); if (line.command == "solution") { // create future commands impact solution properties = &solution; } else if (line.command == "exe" || line.command == "lib") { if (line.params.size() != 1) { cerr << "error @ line " << linenum << endl; homecoming 1; } // create future commands impact project properties = solution.getproject(line.params[0]); properties->type = line.command; properties->name = line.params[0]; } else if (line.command == "includes") { properties->includes = concat(properties->includes, line.params); } else if (line.command == "libpath") { properties->libpaths = concat(properties->libpaths, line.params); } else if (line.command == "libs") { properties->libs = concat(properties->libs, line.params); } else if (line.command == "folder") { if (line.params.size() != 1) { cerr << "error @ line " << linenum << endl; homecoming 1; } properties->folder = line.params[0]; } else if (line.command == "source") { properties->sources = concat(properties->sources, line.params); } else if (line.command == "header") { properties->headers = concat(properties->headers, line.params); } else if (line.command == "depends") { project *proj; (string projname : line.params) { proj = solution.getproject(projname); properties->depends.push_back(proj); } } } }
the error:
heap: free heap block 00395b68 modified @ 00395bac after freed
here stack trace (sorry no line numbers in source above):
crashes in malloc & ntdll somewhere here libstdc++ ---- incomprehensible name mangling main.cpp, line 24 (inside properties::properties()): (compiler-generated constructor) main.cpp, line 37 (inside project::project()): project() { built = false; } main.cpp, line 62 (inside solution::getproject()): project p; main.cpp, line 150 (inside main()): proj = solution.getproject(projname);
it seems crashing in default constructor properties? perhaps while constructing vector?
edit: input file, if help:
solution includes deps/include deps/include/sdl2 libpath deps/lib libs opengl32 glu32 sdl2main sdl2 libpng16 glew exe game folder game source main.cpp depends render mutual lib render folder render source shader.cpp header todo depends mutual lib mutual folder mutual source util.cpp header todo
this lot of code, 1 strong possibility de-referencing 1 of pointers returned getproject
, has been invalidated because vector projects
, holds objects pointed to, has performed re-allocation. invalidates pointers, references , iterators.
when this:
projects.push_back(p);
projects
may need grow, results in re-allocation , invalidation of pointers mentioned above.
without looking code in depth, looks can implement solution
quite trivially using std::map
:
struct solution : properties { public: // check project name "name" // add together 1 if doesn't exist // homecoming project& getproject(const std::string& name) { if (!projects.count(name)) { projects[name].name = name; } homecoming projects[name]; } // homecoming project name "name" or raise exception // if doesn't exist const project& getproject(const string &name) const { homecoming projects.at(name); } private: std::map<std::string, project> projects; };
c++
No comments:
Post a Comment