std::map insert segmentation fault - c++

Why does this code stop with segmentation fault :
class MapFile
{
public:
/* ... */
std::map <unsigned int, unsigned int> inToOut;
};
bool MapFile::LoadMapFile( const wxString& fileName )
{
/* ... */
inToOut.insert( std::make_pair(input,output) );
}
but when I put the "std::map inToOut;" just before "inToOut.insert" it works just fine :
class MapFile
{
public:
/* ... */
};
bool MapFile::LoadMapFile( const wxString& fileName )
{
/* ... */
std::map <unsigned int, unsigned int> inToOut;
inToOut.insert( std::make_pair(input,output) );
}
?
OK. Thanks guys, it seems that I have fixed this issue thanks to your help.
The problem was in the part of the code where I've been calling the LoadMapFile :
void WizardProductPage::OnTestButtonMapFile( wxCommandEvent& event )
{
wxString filename;
filename = locMapFile->GetValue();
MapFile::LoadMapFile( filename );
}
Should be :
void WizardProductPage::OnTestButtonMapFile( wxCommandEvent& event )
{
wxString filename;
filename = locMapFile->GetValue();
MapFile mapFile;
mapFile.LoadMapFile( filename );
}

I guess your problem is somewhere else. The following code works ok:
class MapFile
{
public:
std::map <unsigned int, unsigned int> inToOut;
void LoadMapFile();
};
void MapFile::LoadMapFile()
{
inToOut.insert( std::make_pair(1, 1) );
}
int main() {
MapFile a;
a.LoadMapFile();
return 0;
}
Try step-by-step debugging or post your whole code here, because this has no problems in it.
Also, yes. If you're trying to do that operation from different threads simultaneosly without locking, it could cause segfault.

Most likely you have a buffer overflow or a bad pointer that has caused you to trash the map when it's a member of your class. When you have the class an an auto variable, it is somewhere else in memory and your original bug is trashing some other piece of memory.
You should run your code under a memory debugger. If you are on Linux, I would recommend Valgrind

Maybe your application is multi-threaded and you are not locking insertion into map. Second variant doesn't share map with other threads.

It's possible that you called the member function on a object that has been deleted.
eg.
MapFile *p;
{
MapFile a;
p = &a;
}
p->LoadMapFile("test.map");
Would produce the error you described. The second case would not since you are not dereferencing the this pointer at any time.
edit: Maybe not, in the case that the input,output variables are member data then my answer would be incorrect.

Other reason for this kind of problem could be using a map with custom comparator and/or allocator and not initializing the map accordingly, which could generate segmentation faults at any random point, ie: the first insert could work perfectly, but on the second one, when the compare function is called, there could be a segmentation fault.

Related

Problem while initializing attribute in constructor c++

While i try to debug
ERROR appear :
"Unhandled exception at 0x5784F2F6 (ucrtbased.dll) in Final project.exe: An invalid parameter was passed to a function that considers invalid parameters fatal."
Tried every thing can't figure out how to solve this.
using namespace std;
class Map :
{
private:
double *mhours_played;
string *maps;
unsigned element_num;
public:
Map()
{
maps[2] = { "Summoner's rift", "Aram" };
element_num = 2; mhours_played[2] = {};
}
~Map() { delete[] maps; }
};
These statements
maps[2] = { "Summoner's rift", "Aram" };
mhours_played[2] = {};
do not make sense. maps and mhours_played are pointers that within the body of the constructor have indeterminate values. They are not arrays as you think. For example the expression maps[2] is a scalar object of the type std::string.
Define the constructor at least like
Map() : mhours_played( new double[2]() ),
maps( new std::string[2] { "Summoner's rift", "Aram" } ),
element_num( 2 )
{
}
and the destructor like
~Map()
{
delete[] maps;
delete[] mhours_played;
}
It seems like the key misunderstanding here is the difference between stack and heap allocation. Your code would be (almost) correct if we were normally allocating space for an array in a function:
#include <string>
int main() {
std::string maps[2] = {"Chad", "Zimbabwe"};
}
This is perfectly valid, and works as expected. However, what you're trying to do is dynamically allocate space for an array of strings in memory location maps. This syntax for this would be as follows:
#include <string>
int main() {
std::string* maps;
maps = new std::string[2];
// ... more code ...
// always free your memory!
delete[] maps;
}
This tells the OS, "hey! I want some memory for an array, can I have some?" and the OS (hopefully) says "yeah, here you go have fun."
Currently, your code tries to access the second index in unallocated memory, and the OS really doesn't like that.
I hope this helps, and let me know if you need further clarification.

Save reference to void pointer in a vector during loop iteration

Guys I have a function like this (this is given and should not be modified).
void readData(int &ID, void*&data, bool &mybool) {
if(mybool)
{
std::string a = "bla";
std::string* ptrToString = &a;
data = ptrToString;
}
else
{
int b = 9;
int* ptrToint = &b;
data = ptrToint;
}
}
So I want to use this function in a loop and save the returned function parameters in a vector (for each iteration).
To do so, I wrote the following struct:
template<typename T>
struct dataStruct {
int id;
T** data; //I first has void** data, but would not be better to
// have the type? instead of converting myData back
// to void* ?
bool mybool;
};
my main.cpp then look like this:
int main()
{
void* myData = nullptr;
std::vector<dataStruct> vec; // this line also doesn't compile. it need the typename
bool bb = false;
for(int id = 1 ; id < 5; id++) {
if (id%2) { bb = true; }
readData(id, myData, bb); //after this line myData point to a string
vec.push_back(id, &myData<?>); //how can I set the template param to be the type myData point to?
}
}
Or is there a better way to do that without template? I used c++11 (I can't use c++14)
The function that you say cannot be modified, i.e. readData() is the one that should alert you!
It causes Undefined Behavior, since the pointers are set to local variables, which means that when the function terminates, then these pointers will be dangling pointers.
Let us leave aside the shenanigans of the readData function for now under the assumption that it was just for the sake of the example (and does not produce UB in your real use case).
You cannot directly store values with different (static) types in a std::vector. Notably, dataStruct<int> and dataStruct<std::string> are completely unrelated types, you cannot store them in the same vector as-is.
Your problem boils down to "I have data that is given to me in a type-unsafe manner and want to eventually get type-safe access to it". The solution to this is to create a data structure that your type-unsafe data is parsed into. For example, it seems that you inteded for your example data to have structure in the sense that there are pairs of int and std::string (note that your id%2 is not doing that because the else is missing and the bool is never set to false again, but I guess you wanted it to alternate).
So let's turn that bunch of void* into structured data:
std::pair<int, std::string> readPair(int pairIndex)
{
void* ptr;
std::pair<int, std::string> ret;
// Copying data here.
readData(2 * pairIndex + 1, ptr, false);
ret.first = *reinterpret_cast<int*>(ptr);
readData(2 * pairIndex + 2, ptr, true);
ret.second = *reinterpret_cast<std::string*>(ptr);
}
void main()
{
std::vector<std::pair<int, std::string>> parsedData;
parsedData.push_back(readPair(0));
parsedData.push_back(readPair(1));
}
Demo
(I removed the references from the readData() signature for brevity - you get the same effect by storing the temporary expressions in variables.)
Generally speaking: Whatever relation between id and the expected data type is should just be turned into the data structure - otherwise you can only reason about the type of your data entries when you know both the current ID and this relation, which is exactly something you should encapsulate in a data structure.
Your readData isn't a useful function. Any attempt at using what it produces gives undefined behavior.
Yes, it's possible to do roughly what you're asking for without a template. To do it meaningfully, you have a couple of choices. The "old school" way would be to store the data in a tagged union:
struct tagged_data {
enum { T_INT, T_STR } tag;
union {
int x;
char *y;
} data;
};
This lets you store either a string or an int, and you set the tag to tell you which one a particular tagged_data item contains. Then (crucially) when you store a string into it, you dynamically allocate the data it points at, so it will remain valid until you explicitly free the data.
Unfortunately, (at least if memory serves) C++11 doesn't support storing non-POD types in a union, so if you went this route, you'd have to use a char * as above, not an actual std::string.
One way to remove (most of) those limitations is to use an inheritance-based model:
class Data {
public:
virtual ~Data() { }
};
class StringData : public Data {
std::string content;
public:
StringData(std::string const &init) : content(init) {}
};
class IntData : public Data {
int content;
public:
IntData(std::string const &init) : content(init) {}
};
This is somewhat incomplete, but I think probably enough to give the general idea--you'd have an array (or vector) of pointers to the base class. To insert data, you'd create a StringData or IntData object (allocating it dynamically) and then store its address into the collection of Data *. When you need to get one back, you use dynamic_cast (among other things) to figure out which one it started as, and get back to that type safely. All somewhat ugly, but it does work.
Even with C++11, you can use a template-based solution. For example, Boost::variant, can do this job quite nicely. This will provide an overloaded constructor and value semantics, so you could do something like:
boost::variant<int, std::string> some_object("input string");
In other words, it's pretty what you'd get if you spent the time and effort necessary to finish the inheritance-based code outlined above--except that it's dramatically cleaner, since it gets rid of the requirement to store a pointer to the base class, use dynamic_cast to retrieve an object of the correct type, and so on. In short, it's the right solution to the problem (until/unless you can upgrade to a newer compiler, and use std::variant instead).
Apart from the problem in given code described in comments/replies.
I am trying to answer your question
vec.push_back(id, &myData<?>); //how can I set the template param to be the type myData point to?
Before that you need to modify vec definition as following
vector<dataStruct<void>> vec;
Now you can simple push element in vector
vec.push_back({id, &mydata, bb});
i have tried to modify your code so that it can work
#include<iostream>
#include<vector>
using namespace std;
template<typename T>
struct dataStruct
{
int id;
T** data;
bool mybool;
};
void readData(int &ID, void*& data, bool& mybool)
{
if (mybool)
{
data = new string("bla");
}
else
{
int b = 0;
data = &b;
}
}
int main ()
{
void* mydata = nullptr;
vector<dataStruct<void>> vec;
bool bb = false;
for (int id = 0; id < 5; id++)
{
if (id%2) bb = true;
readData(id, mydata, bb);
vec.push_back({id, &mydata, bb});
}
}

Position in Member Declaration Breaks Code?

A while ago I asked a question on why the following code did not work:
std::vector<std::vector<std::vector<Tile_Base*>>> map_tile; // This is located in Map object. See below.
int t_x, t_y;
t_x = t_y = 200;
map_tiles.begin(); // clear(), resize() and every other function still causes problems
The thing is, is that it should have worked, yet Visual Studios 2012 throws an exception when the resize function is called. The exception pointed to this piece of code:
*_Pnext != 0; *_Pnext = (*_Pnext)->_Mynextiter)
located in xutility. It said that there was an violating on access to reading the memory. I thought maybe somehow I lost access to the member along the way? (Using VS' watch I saw the memory was not corrupted)
So, I fiddled around with the code and tried to figure out what could possibly be going wrong, and after awhile I moved the map_tiles object down to the bottom of the list, and it worked:
// WORKS
class Map {
std::vector<Tile_Base*> spawn_tiles;
// map tile specific
bool Is_Valid(int,int);
std::string name;
std::vector<std::vector<std::vector<Tile_Base*> > > map_tiles;
public:
// ...
}
// DOESN'T WORK
class Map {
std::vector<std::vector<std::vector<Tile_Base*> > > map_tiles;
std::vector<Tile_Base*> spawn_tiles;
// map tile specific
bool Is_Valid(int,int);
std::string name;
public:
// ...
}
Any help pointing out what went wrong? I can't come up with any reasonable explanation.
A vector<T> comprises two discrete sets of data: the internal state and the array of Ts. The internal state - capacity, size, pointer - is separate from the array. The issue you're describing is normally caused by something overwriting the vector object, i.e the internal state. To track this down easily you could use a container class:
typedef std::vector<std::vector<std::vector<Tile_Base*> > > maptiles_t;
class CMapTiles
{
unsigned int m_guard;
maptiles_t m_tiles;
enum { Guard = 0xdeadbeef };
public:
CMapTiles() : m_guard(Guard), m_tiles() {}
~CMapTiles() { assert(m_guard == Guard); }
void Check()
{
#if defined(DEBUG)
if (m_guard != Guard)
DebugBreak();
#endif
}
void Resize(size_t x, size_t y)
{
Check();
auto init = std::vector<std::vector<Tile_Base*> >(y/32);
m_tiles.resize(m_x / 32, init);
Check();
}
const maptiles_t& tiles() const { Check(); return m_tiles; }
maptiles_t& tiles() { Check(); return m_tiles; }
};
And instead of using std::vector<...> map_tiles have CMapTiles map_tiles, and then when you want to get at the vector, map_tiles.tiles().
Hope this helps.

Segfault after using pointers in vector in C++

i am running into a segfault in my c++ program and can't figure out my mistake.
I have a class Map which is a 2D-vector of objects of the class MapCells. The task is to go from cell to cell. From each cell, there are two possible ways to other cells. Maybe some 'pseudo' code can explain it better:
//map.h
class MapCell {
private:
MapCell *p_way1_, *p_way2_;
int some_information_;
public:
MapCell* getWayPointer1();
MapCell* getWayPointer2();
int getInformation();
void setWayPointer1(MapCell* new_p_way1);
void setWayPointer1(MapCell* new_p_way2);
};
class Map {
private:
std::vector< std::vector<MapCell> > map_;
public:
void initializeMap();
MapCell* getStartPointer();
};
int main()
{
Map map;
map.initializeMap();
MapCell *p_current_cell, *p_next_cell;
p_current_cell = map.getStartPointer();
while(p_current_cell->getInformation() != 0)
{
if(p_current_cell->getInformation() == 1)
{
p_next_cell = p_current_cell->getWayPointer1();
}
else
{
p_next_cell = p_current_cell->getWayPointer2();
}
p_current_cell = p_next_cell;
}
return 0;
}
This is only a little part of the real code. But i think i made a fundamental mistake so i hope this is enough code to fix it.
The problem is, that my code runs for minutes without problems and suddenly i get a segfault. gdb states, that the segfault happens when getInformation() is called. I also found out, that at some point all p_way2_ vectors lead to nonsense. Can you help me?
Thank you very much in advance!
Problem in lines
MapCell* p_current_cell, p_next_cell;
MapCell* p_way1_, p_way2;
Second parameter is not pointer and MapCell is implicit convert from pointers (or you will get multiple compile-times errors).
Try change to
MapCell* p_current_cell, *p_next_cell;
MapCell* p_way1_, *p_way2;

How to modify a C++ structure with int *

I have the following structure:
struct CountCarrier
{
int *CurrCount;
};
And this is what I want to do:
int main()
{
CountCarrier carrier = CountCarrier();
*(carrier.CurrCount) = 2; // initialize the *(carrier.CurrCount) to 2
IncreaseCount(&carrier); // should increase the *(carrier.CurrCount) to 3
}
void IncreaseCount(CountCarrier *countCarrier)
{
int *currCounts = countCarrier->CurrCount;
(*currCounts)++;
}
So, my intention is specified in the comments.
However, I couldn't get this to work. For starters, the program throws an exception at this line:
*(carrier.CurrCount) = 2;
And I suspect the following line won't work as well. Anything I did wrong?
struct CountCarrier
{
int *CurrCount; //No memory assigned
};
You need to allocate some valid memory to the pointer inside the structure to be able to put data in this.
Unless you do so, What you ar trying to do is attempting to write at some invalid address, which results in an Undefined Behavior, which luckiy in this case shows up as an exception.
Resolution:
struct CountCarrier
{
int *CurrCount; //No memory assigned
CountCarrier():CurrCount(new(int))
{
}
};
Suggestion:
Stay away from dynamic allocations as long as you can.
When you think of using pointers always think whether you really need one. In this case it doesn't really seem that you need one, A simple int member would be just fine.
You need to create the pointer. ie. carrier->CurrCount = new int;
*(carrier.CurrCount)
This is dereferencing the pointer carrier.CurrCount, but you never initialized it. I suspect this is what you want:
carrier.CurrCount = new int(2);
I seriously doubt that your program throws an exception at the line:
*(carrier.CurrCount) = 2;
While throwing an exception is certainly allowed behaviour, it seems much more likely that you encountered an access violation that caused the process to be killed by the operating system.
The problem is that you are using a pointer, but your pointer is not initialised to point at anything. This means that the result of the pointer dereference is undefined.
In this situation there does not seem to be any advantage to using a pointer at all. Your CurrCount member would work just as well if it was just a plain int.
If you are using C++, then you should encash its facilities. Instead of correcting your code, I am showing here that how the code should look like:
struct CountCarrier
{
int CurrCount; // simple data member
CountCarrier(int count) : CurrCount(count) {} // constructor
CountCarrier& operator ++ () // overloaded operator
{
++ CurrCount;
return *this;
}
};
We are overloading operator ++, because you have only one data member. You can replace with some named method also, like void IncrementCount().
CountCarrier carrier(2);
++ carrier;
As Als said, you need to provide some memory for the code to work.
But why make it so complicated? You don't need any pointers for the code you have to work. The "modern C++" way looks more like this:
struct CountCarrier
{
public:
CountCarrier(int currCount) : currCount(currCount) {}
void IncreaseCount() { ++currCount; }
int GetCount() const { return currCount; }
private:
int currCount;
};
int main()
{
CountCarrier carrier(2); // Initialize carrier.currCount to 2
carrier.IncreaseCount(); // Increment carrier.currCount to 3
}
Note how much cleaner and less error prone that is. Like I said, pick up a good introductory C++ book and read through it.