Seg Fault Help

S

subaruwrx88011

I am using a map that takes an string as the key and a structure that
is being stored.

struct StateType
{
int i;
float f;
char* s;
}

typedef std::map<std::string, StateType> ItemStateMap;

ItemStateMap m_itemMap;

StateType state;
state.s = "HelloWorld";

m_itemMap["FirstPosition"] = state;


This is a really watered down version of what I am doing but this is
exactly what its doing in a nutshell. I am getting a segmentation fault
on m_itemMap["FirstPosition"] = state. Can anyone tell me what I am
doing wrong? I tried to use
m_itemMap.insert("FirstPosition", state) but that wouldn't compile.

Thanks in advance
subaruwrx88011
 
B

Ben Pope

subaruwrx88011 said:
I am using a map that takes an string as the key and a structure that
is being stored.

struct StateType
{
int i;
float f;
char* s;
}

typedef std::map<std::string, StateType> ItemStateMap;

ItemStateMap m_itemMap;

StateType state;
state.s = "HelloWorld";

m_itemMap["FirstPosition"] = state;


This is a really watered down version of what I am doing but this is
exactly what its doing in a nutshell. I am getting a segmentation fault
on m_itemMap["FirstPosition"] = state. Can anyone tell me what I am
doing wrong? I tried to use
m_itemMap.insert("FirstPosition", state) but that wouldn't compile.

I'll tell you what you are doing wrong. You're not listening, and not
learning. POST COMPILABLE CODE.

We cannot tell you what is wrong with a "watered down version" if the
watered down version does not exhibit the problem.

At the moment the problem is the last two lines; they exist at file
scope, they need to go inside main, or another function.

Ben Pope
 
V

Victor Bazarov

subaruwrx88011 said:
I am using a map that takes an string as the key and a structure that
is being stored.

struct StateType
{
int i;
float f;
char* s;
}

A semicolon seems to be missing here...
typedef std::map<std::string, StateType> ItemStateMap;

ItemStateMap m_itemMap;

StateType state;
state.s = "HelloWorld";

This is a VERY BAD IDEA(tm). Your member is a pointer to 'char', and you
are assigning a pointer to a const char to it.
m_itemMap["FirstPosition"] = state;


This is a really watered down version of what I am doing but this is
exactly what its doing in a nutshell.

Too much water. Post _real_ code. Your fragment as posted doesn't even
compile. Always post code that can be copied, pasted into a file, and
passed to a compiler without any changes.
> I am getting a segmentation fault
on m_itemMap["FirstPosition"] = state. Can anyone tell me what I am
doing wrong? I tried to use
m_itemMap.insert("FirstPosition", state) but that wouldn't compile.

Of course it won't. 'insert' that you're trying to use takes one argument
-- a pair. RTFM.

V
 
H

Howard

subaruwrx88011 said:
I am using a map that takes an string as the key and a structure that
is being stored.

struct StateType
{
int i;
float f;
char* s;

Prefer to use std::string over a raw char array for s.
}

typedef std::map<std::string, StateType> ItemStateMap;

ItemStateMap m_itemMap;

StateType state;
state.s = "HelloWorld";

This points the member s pointer to a local const char. No memory is
allocated specifically for s, and if this constant goes out of scope, then s
points to invalid memory. Either allocated an array for s dynamically and
use strcpy to fill it, or use std::string.
m_itemMap["FirstPosition"] = state;

I'm not positive if this is how to assign to a map, but even if it is, it's
going to make a copy of the state object. And unless you define a copy
construcor for StateType, then it's only going to do a "shallow" copy, which
means that the member s will point to the same const char array that state's
s member points to. You need a valid copy constructor which allocates
memory for s and copies the data into it. (Again, it would be easier to use
std::string.)
This is a really watered down version of what I am doing but this is
exactly what its doing in a nutshell. I am getting a segmentation fault
on m_itemMap["FirstPosition"] = state. Can anyone tell me what I am
doing wrong? I tried to use
m_itemMap.insert("FirstPosition", state) but that wouldn't compile.

(Sorry, I'm not up on maps. But I hope my other thoughts are helpful.)

-Howard
 
T

TB

subaruwrx88011 sade:
I am using a map that takes an string as the key and a structure that
is being stored.

struct StateType
{
int i;
float f;
char* s;
}

Missing semicolon.
typedef std::map<std::string, StateType> ItemStateMap;

ItemStateMap m_itemMap;

StateType state;
state.s = "HelloWorld";

m_itemMap["FirstPosition"] = state;

Why not provide a complete compilable code, instead of something
partial. Does this work?

#include <string>
#include <map>

struct StateType {
char const * d_cptr;
};

int main(int argc, char** argv)
{
std::map<std::string, StateType> m;
StateType state = {"HelloWorld"};
m["FirstPosition"] = state;
return 0;
}
This is a really watered down version of what I am doing but this is
exactly what its doing in a nutshell. I am getting a segmentation fault
on m_itemMap["FirstPosition"] = state. Can anyone tell me what I am
doing wrong? I tried to use
m_itemMap.insert("FirstPosition", state) but that wouldn't compile.

m_itemMap.insert( std::make_pair("FirstPosition", state) );
 
B

Ben Pope

Ben said:
I'll tell you what you are doing wrong. You're not listening, and not
learning. POST COMPILABLE CODE.

If I've bundled you in with somebody else asking an unnervingly similar
question, and you are not, in fact CQ, then I apologise.

Ben Pope
 
S

subaruwrx88011

Ok sorry guys I am really new at c++ and how this forum works.

Here is the real code.

class CCSI_EnviromentClass
{
private:

//Constructor
CCSI_EnviromentClass();


typedef struct StateType
{
int i;
char* s;
float f;
StateType() : i(-1), f(1.0) {}
};

typedef std::map<std::string, StateType> ItemStateMap;
ItemStateMap m_itemMap;
static CCSI_EnviromentClass *ms_instance;

public:
//Destructor
~CCSI_EnviromentClass();

//Methods
static CCSI_EnviromentClass *instance();
int getItemStateInt(char* item);
float getItemStateFloat(char* item);
char* getItemStateString(char* item);

int setItemState(std::string item, char* state);
int setItemState(std::string item, float state);
int setItemState(std::string item, int state);

void print();
};

char* CCSI_EnviromentClass::getItemStateString(char* item)
{
StateType state;

ItemStateMap::iterator map_iterator;

//Find the item name in the list
map_iterator = m_itemMap.find(item);

//If the item was found then return the state, otherwise return NULL
if(map_iterator != m_itemMap.end())
{
state = m_itemMap[item];
return state.s; //return string part of union
}
else
{
return NULL;
}
}

float CCSI_EnviromentClass::getItemStateFloat(char* item)
{
StateType state;

ItemStateMap::iterator map_iterator;

//Find the item name in the list
map_iterator = m_itemMap.find(item);

//If the item was found then return the state, otherwise return NULL
if(map_iterator != m_itemMap.end())
{
state = m_itemMap[item];
return state.f; //return float part of union
}
else
{
return -1;
}
}

int CCSI_EnviromentClass::getItemStateInt(char* item)
{
StateType state;

ItemStateMap::iterator map_iterator;

//Find the item name in the list
map_iterator = m_itemMap.find(item);

//If the item was found then return the state, otherwise return NULL
if(map_iterator != m_itemMap.end())
{
state = m_itemMap[item];
return state.i; //return float part of union
}
else
{
return -1;
}
}

int CCSI_EnviromentClass::setItemState(std::string p_item, char*
p_state)
{
StateType state;
state.s = p_state;
m_itemMap[p_item] = state;
return 0;
}

int CCSI_EnviromentClass::setItemState(std::string p_item, float
p_state)
{
StateType state;
state.f = p_state;
m_itemMap[p_item] = state;
return 0;
}

int CCSI_EnviromentClass::setItemState(std::string p_item, int
p_state)
{
StateType state;
state.i = p_state;
m_itemMap[p_item] = state;
return 0;
}



Hope this is better.
 
V

Victor Bazarov

subaruwrx88011 said:
Ok sorry guys I am really new at c++ and how this forum works.

Here is the real code.

class CCSI_EnviromentClass
{
private:

//Constructor
CCSI_EnviromentClass();


typedef struct StateType
{
int i;
char* s;
float f;
StateType() : i(-1), f(1.0) {}

So, you initialise all except 's'. 's' is left _uninitialised_. If
a pointer is uninitialised, it contains _garbage_, it points _nowhere_.
Initialise it to 0, at least then you can _verify_ whether it has some
"real" value or "nothing".
};

typedef std::map<std::string, StateType> ItemStateMap;
ItemStateMap m_itemMap;
static CCSI_EnviromentClass *ms_instance;

public:
//Destructor
~CCSI_EnviromentClass();

The constructor is private, the destructor is public. Is there any
particular reason?
//Methods
static CCSI_EnviromentClass *instance();
int getItemStateInt(char* item);
float getItemStateFloat(char* item);
char* getItemStateString(char* item);

OK... The map is based on 'std::string'. You're passing bare pointers
around. Is there a particular reason?
int setItemState(std::string item, char* state);
int setItemState(std::string item, float state);
int setItemState(std::string item, int state);

void print();
};

char* CCSI_EnviromentClass::getItemStateString(char* item)
{
StateType state;

ItemStateMap::iterator map_iterator;

//Find the item name in the list
map_iterator = m_itemMap.find(item);

//If the item was found then return the state, otherwise return NULL
if(map_iterator != m_itemMap.end())
{
state = m_itemMap[item];
return state.s; //return string part of union

It is better to do

return (*map_iterator).second.s;

here to avoid another search that would inevitably performed when you
use the indexing operator.
}
else
{
return NULL;
}
}

float CCSI_EnviromentClass::getItemStateFloat(char* item)
{
StateType state;

ItemStateMap::iterator map_iterator;

//Find the item name in the list
map_iterator = m_itemMap.find(item);

//If the item was found then return the state, otherwise return NULL
if(map_iterator != m_itemMap.end())
{
state = m_itemMap[item];
return state.f; //return float part of union

Same note as above
}
else
{
return -1;
}
}

int CCSI_EnviromentClass::getItemStateInt(char* item)
{
StateType state;

ItemStateMap::iterator map_iterator;

//Find the item name in the list
map_iterator = m_itemMap.find(item);

//If the item was found then return the state, otherwise return NULL
if(map_iterator != m_itemMap.end())
{
state = m_itemMap[item];
return state.i; //return float part of union

And here, too.
}
else
{
return -1;
}
}

int CCSI_EnviromentClass::setItemState(std::string p_item, char*
p_state)
{
StateType state;
state.s = p_state;
m_itemMap[p_item] = state;
return 0;
}

int CCSI_EnviromentClass::setItemState(std::string p_item, float
p_state)
{
StateType state;
state.f = p_state;
m_itemMap[p_item] = state;
return 0;
}

int CCSI_EnviromentClass::setItemState(std::string p_item, int
p_state)
{
StateType state;
state.i = p_state;
m_itemMap[p_item] = state;
return 0;
}



Hope this is better.

Actually, just a tiny bit better. But of course, since you never show
_who_ uses those functions (especially the suspect 'setItemState') and
_how_ they are used (what is passed to them), there is no way to tell,
again. The code is real alright. However, it's _incomplete_.

V
 
V

Victor Bazarov

Howard said:
This points the member s pointer to a local const char.

No. It points the member 's' to a string literal.
> No memory is
allocated specifically for s, and if this constant goes out of scope, then s
points to invalid memory.

A string literal _never_ goes "out of scope".
> Either allocated an array for s dynamically and
use strcpy to fill it, or use std::string.

V
 
H

Howard

Victor Bazarov said:
No. It points the member 's' to a string literal.


A string literal _never_ goes "out of scope".

Ah, quite so. So is this a valid way to assign to a char*? I had thought
it was a valid initializer, but not a valid assignment.

-Howard
 
D

Default User

Howard said:
This points the member s pointer to a local const char. No memory is
allocated specifically for s, and if this constant goes out of scope,
then s points to invalid memory.

This is not correct. The chars inside "" form a string literal, which
is not local at all. It will exist for the lifetime of the program.
There are good reasons for not doint that (Victor pointed out the main
one) but yours isn't correct.



Brian
 
V

Victor Bazarov

Howard said:
[..] So is this a valid way to assign to a char*? I had thought
it was a valid initializer, but not a valid assignment.

Well, I don't remember. You're probably correct. Some compilers let it
through, however.

V
 
S

subaruwrx88011

Ok i changed it to use std::string. Now in my application in need to
check to see if that string was stored. I was using
if(state.s != NULL), but that doesn't work now since state.s is
std::string. How do I go about checking this?
 
R

roberts.noah

subaruwrx88011 said:
Ok i changed it to use std::string. Now in my application in need to
check to see if that string was stored. I was using
if(state.s != NULL), but that doesn't work now since state.s is
std::string. How do I go about checking this?

You may need a variable to tell you such is the case. Or you could use
std::string* and do the same thing. Or, if "" is not a valid value,
you could check that state.s.size() > 0.
 
D

Default User

Victor said:
Howard said:
[..] So is this a valid way to assign to a char*? I had thought
it was a valid initializer, but not a valid assignment.

Well, I don't remember. You're probably correct. Some compilers let
it through, however.

It's valid, but deprecated (and a very BAD idea).

From the standard:

4.2 Array-to-pointer conversion

2 A string literal (2.13.4) that is not a wide string literal can be
converted to an rvalue of type "pointer to char"; a wide string literal
can be converted to an rvalue of type "pointer to wchar_t". In either
case, the result is a pointer to the first element of the array. This
conversion is considered only when there is an explicit appropriate
pointer target type, and not when there is a general need to convert
from an lvalue to an rvalue. [Note: this conversion is deprecated. See
Annex D. ]

Annex D:

D.4 Implicit conversion from const strings
1 The implicit conversion from const to non-const qualification for
string literals (4.2) is deprecated.



Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Map Seg Fault 17
Why does this cause a seg fault? 1
C99 Seg fault on while(), why ? 0
Wierd Map Behavior 5
Map Question 4
Chatbot 0
seg fault 11
Strange seg fault 4

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top