C/C++ string memory allocation - c++

I've just recently begun with C/C++ development on an embedded system (ARM - STM32F4 to be more specific) and I am now having almost classical problems of someone who isn't used to C or low level memory managment.
Basically I have a class MenuOption that inherits some field from some other class and basically looks like this:
...
char text[20];
...
void MenuOption::setText(const char* text1)
{
clearCurrent();
needsUpdate = true;
strncpy(text, text1, 20);
width = font->FontWidth*strlen(text);
}
The constructor for this class calls that setText method to store the text. This works fine if I use it like this inside a main function:
std::vector<MenuOption *> mainMenuOptions;
MenuOption* op1 = new MenuOption(13, 15, "Info", WHITE, BLACK);
op1->setSelected(true);
mainMenuOptions.push_back(op1);
But it fails when I want to use it like this:
std::vector<MenuOption *> options;
for (int i = 0; i < things.size(); i++)
{
Thing *th = things[i];
... do some stuff with th ...
MenuOption* op = new MenuOption(190, 38+25*i, "test", WHITE, BLACK);
options.push_back(op);
}
This fails (debugger sort of stalls) at the MenuOption* op ... line. Now I am guessing that this isn't something that I should be doing. But I can't seem to find a working solution.
EDIT:
To answer everyones questions. This does in fact compile with a C++ compiler. GCC using C++11 dialect.
There is a reason why I am using C strings instead of std::string. I am using a few C libraries that need C strings. And whenever I tried to convert that string into a C string inside a FreeRTOS task the thing would fail. The same problem as now actually.
No other breakpoint inside the task will trigger after it reaches that constructor line. I can't step in or skip a line or anything like that at that line. I have a feeling it gets caught by a hard_fault interrupt handler. Other tasks would continue to run. That's the problem. There are no errors or anything that would point me to the cause. The same problem was when I was using std::string when I tried to create a new MenuOption inside a FreeRTOS task. The thing works if I remove the string from the constructor. So I am guessing that it has something to do with strings.
As for string length. I know that strings used here will not be longer than 15 characters. I used those 5 characters for pure "backup"-
As for the ... do some stuff with th ... that was just this: th->flag = true;. I didn't do anything more with it because of this problem.

The tip posted in the comments by Étienne was actually what lead me to the answer. More specifically I found this: http://www.freertos.org/FreeRTOS_Support_Forum_Archive/October_2013/freertos_Using_C_std_vector_in_task_93928e86j.html
void *operator new(size_t size)
{
void *p;
if(uxTaskGetNumberOfTasks())
p=pvPortMalloc(size);
else
p=malloc(size);
return p;
}
void operator delete(void *p)
{
if(uxTaskGetNumberOfTasks())
vPortFree( p );
else
free( p );
p = NULL;
}

Related

seg fault after end of function (C++)

I'm having a seg fault: 11 when I run a particular program. I feel like this problem wasn't present before I upgraded my system to Mac OS X 10.9, but it's possible I just overlooked it..
Anyway, my function looks like:
// this applies a warp to the field given, and saves output. simple!
void Apply(string warpName, string fieldName, bool conserve, string outName) {
// get lon, lat dimensions of warp
int noLongs = GetDimension(warpName, 3, "warp");
int noLats = GetDimension(warpName, 2, "warp");
int origNoLongs = noLongs, origNoLats = noLats;
// read in params
vector<double> params = ImportWarpFromNetCDF(warpName);
// rescale field to warp's dimensions, and read in
string tempName = "scaledField";
ReScale(fieldName, tempName, noLongs, noLats);
vector<vector<vector<double> > >inIntensities = ImportFieldFromNetCDF(tempName);
RemoveFile(tempName);
// just enter inIntensities for ref image, and 1 for lambda, to keep objective function happy
ObjectiveFunction objective(inIntensities, inIntensities, conserve, 1, false);
objective.setParameters(params);
// output files
ExportOutputToNetCDF(objective, outName);
cout << "BAH?!" << endl;
}
where the cout line at the end was just checking to see I'd got to the end of the function properly (which I have). Any thoughts on why this would be segfaulting here? I appreciate it might be hard to tell without seeing what the individual function calls do, and so I'll add those if necessary.
It doesn't actually matter too much, as this function is the last thing to be called (so the seg fault doesn't interrupt anything), but I still would rather get to the bottom of it!
The only thing that happens "after" the function are destructor calls. Check all your destructors of local variables. It looks like ObjectiveFunction is the only local variable that's not a primitive or standard library container, so check ObjectiveFunction::~ObjectiveFunction() for potential problems.

Access violation on std::function assignement using lambdas

Hy everyone, here again. Continuing the code from my previous question : Is this a bad hack? memcpy with virtual classes
I corrected that, using the Clone approach as suggested, but I'm having an error that also happened before I tried the memcpy thing(read question above).
What I'm trying to do is to create a lambda that captures the current script and executes it, and then pass and store that lambda in an object ( Trigger*), in the member InternalCallback.
I get an access violation error on the lambda assignment: http://imgur.com/OKLMJpa
The error happens only at the 4th iteration of this code:
if(CheckHR(EnginePTR->iPhysics->CreateFromFile(physicsPath,StartingTriggerID,trans,scale,-1,false,engPtr)) == HR_Correct)
{
_Lua::ScriptedEntity * newScript = EntityBase->Clone(vm);//nullptr;
string luaPath = transforms.next_sibling().next_sibling().first_attribute().as_string();
if(UseRelativePaths)
{
stringstream temp2;
temp2 << _Core::ExePath() << LuaSubfolder << "\\" << luaPath;
luaPath = temp2.str();
}
newScript->CompileFile(luaPath.c_str());
newScript->EnginePTR_voidptr = engPtr;
auto callback = [=](_Physics::Trigger* trigger,PxTriggerPair* pairs, PxU32 count)
{
newScript->SelectScriptFunction("TriggerCallback");
newScript->AddParam(trigger->Id);
auto data = (_Physics::RayCastingStats*)pairs->otherShape->userData;
newScript->AddParam((PxU8)pairs->flags);
newScript->AddParam(data->ID);
newScript->AddParam((int)data->Type);
newScript->AddParam((int)count);
newScript->Go(1);
return;
};
((_Physics::Trigger*)EnginePTR->iPhysics->GetPhysicObject(StartingTriggerID))->InternalCallback = callback;
StartingTriggerID++;
}
This is the code for Trigger
class Trigger : public PhysicObject
{
public:
Trigger()
{
ActorDynamic = nullptr;
ActorStatic = nullptr;
InternalCallback = nullptr;
}
virtual HRESULT Update(float ElapsedTime,void * EnginePTR);
virtual HRESULT Cleanup(); // Release the actor!!
long Id;
ShapeTypes Type;
static const PhysicObjectType PhysicsType = PhysicObjectType::Trigger;
PxVec3 Scale;
void* UserData;
void Callback(PxTriggerPair* pairs,PxU32 count)
{
InternalCallback(this,pairs,count);
}
function<void(_Physics::Trigger* trigger,PxTriggerPair* pairs, PxU32 count)> InternalCallback;
};
By iteration I mean that is part of a for loop.
My system is Win 7 64 bits, Intel i3, NVIDIA GTX 480, and the compiler Visual Studio 2012 Express, using the C++11 toolset.
I'm really out of ideas. I tested for heap corruption, it appears to be good, I changed the capture in the lambda, changed nothing, I skip the 4th object and it works.
Any help would be really appreciated.
Edit: As required, here is the callstack: http://imgur.com/P7P3t4k
Solved. It was a design error. I store a lot of objects in a map, and they all derive from an object class ( like above, where Trigger derives from PhysicObject ).
The problem was that I was having IDs collisions, so the object stored in ID 5 wasn't a Trigger, so the cast created a bad object, and so the program crashed.
Silly error, really specific, but it might help somebody to remember to check temporal objects.

Cocos2d-x: Crash when initiating TMXTiledMap from string

I'm having problems creating a tmx map from string input.
bool LevelManager::initLevel(int currentLevel)
{
const char* map;
try {
map = LevelManager::getLevel(currentLevel);
} catch (int) {
throw 1;
}
if(map != NULL){
CCLog("%s", map);
tileMap = CCTMXTiledMap::create(map);
tileMap->setAnchorPoint(ccp(0,0));
tileMap->setPosition(ccp(15,20));
this->addChild(tileMap, 5);
backgoundLayer = tileMap->layerNamed("Background");
} else {
throw 1;
}
return true;
}
Thats my code.
It is very unstable. Most of the times it crashes and sometimes it doesn't.
I'm loading my map from the string map. Wich is a const *char.
My map is named Level1.tmx and when i load the map like this: tileMap = CCTMXTiledMap::create("Level1.tmx"); it always works and never crashes.
And i know for a fact that the value of map is Level1.tmx because i log it in the line before the load.
When it crashes the log outputs this: (lldb)
and on the line tileMap->setAnchorPoint(ccp(0,0)); it says "Thread 1: EXC_BAD_ACCESS (code=2, adress=0x0)
Does anyone know why this happens and how to fix it?
Many thanks.
Ps: i'm using xcode, the latest cocos2d-x release and the iPhone simulator
Edit:
Using breakpoints i checked where things go bad while loading the tilemap.
on the line tileMap = CCTMXTiledMap::create(map);
my variable map is still fine
but on line tileMap->setAnchorPoint(ccp(0,0));
it is suddenly corrupted (most of the time)
It sounds like you're returning a char* string created on the stack, which means the memory may or may not be corrupted, depending on circumstances, moon phases, and what not.
So the question is: How is getLevel defined and what does it do (post the code)?
If you do something like this:
const char* LevelManager::getLevel(int level)
{
char* levelName = "default.tmx";
return levelName;
}
…then that's going to be the culprit. The levelName variable is created on the stack, no memory (on the heap) is allocated for it. The levelName variable and the memory it points to become invalid as soon as the method returns.
Hence when the method leaves this area of memory where levelName points to can be allocated by other parts of the program or other method's stack memory. Whatever is in that area of memory may still be the string, or it may be (partially) overridden by other bits and bytes.
PS: Your exception handling code is …. well it shows a lack of understanding what exception handling does, how to use it and especially when. I hope these are just remnants of trying to get to the bottom of the issue, otherwise get rid of it. I recommend reading a tutorial and introductions on C++ exception handling if you want to continue to use exceptions. Especially something like (map != NULL) should be an assertion, not an exception.
I fixed it.
const char* was to blame.
When returning my map as a char * it worked flawless.
const char *levelFileName = level.attribute("file").value();
char *levelChar = new char[strlen(levelFileName) + 1];
std:: strcpy (levelChar, levelFileName);
return levelChar;
Thats how i now return the map.

Calling Function Overwrites Value

I have several configuration flags that I am implementing as structs. I create an object. I call a method of the object with a flag, which eventually triggers a comparison between two flags. However, by this time, one of the flags has been overwritten somehow.
To clarify, here's a VERY simplified version of the code that should illustrate what I'm seeing:
class flag_type { unsigned int flag; /*more stuff*/ };
flag_type FLAG1
flag_type FLAG2
class MyObject {
public:
void method1(const flag_type& flag_arg) {
//conditionals, and then:
const flag_type flag_args[2] = {flag_arg,flag_arg};
method2(flag_args);
}
void method2(const flag_type flag_args[2]) {
//conditionals, and then:
method3(flag_args[0]);
}
void method3(const flag_type& flag_arg) { //Actually in a superclass
//stuff
if (flag_arg==FLAG1) { /*stuff*/ }
//stuff
}
};
int main(int argc, const char* argv[]) {
//In some functions called by main:
MyObject* obj = new MyObject();
//Later in some other functions:
obj->method1(FLAG1);
}
With a debugger and print statements, I can confirm that both FLAG1 and flag_arg/flag_args are fine in both "method1" and "method2". However, when I get to method3, "FLAG1.flag" has been corrupted, so the comparison fails.
Now, although I'm usually stellar about not doing it, and it passes MSVC's static code analysis on strictest settings, this to me looks like the behavior of a buffer overrun.
I haven't found any such error by looking, but of course one usually doesn't. My question isA: Am I screwing up somewhere else? I realize I'm not sharing any real code, but am I missing something already? This scheme worked before before I rewrote a large portion of the code.
B: Is there an easier way than picking through the code more carefully until I find it? The code is cross-platform, so I'm already setting it up to check with Valgrind on an Ubuntu box.
Thanks to those who tried to help. Though, it should be noted that the code was for clarification purposes only; I typed it from scratch to show generally was was happening; not to compile. In retrospect, I realize it wasn't fair to ask people to solve it on so little information--though my actual question "Is there an easier way than picking through the code more carefully" didn't really concern actually solving the problem--just how to approach it.
As to this question, on Ubuntu Linux, I got "stack smashing" which told me more or less where the problem occurred. Interestingly, the traceback for stack smashing was the most helpful. Long story short, it was an embarrassingly basic error; strcpy was overflowing (in the operators for ~, | and &, the flags have a debug string set this way). At least it wasn't me who wrote that code. Always use strncpy, people :P

What could cause initialization order to corrupt the stack?

Question is in bold below :
This works fine:
void process_batch(
string_vector & v
)
{
training_entry te;
entry_vector sv;
assert(sv.size() == 0);
...
}
However, this causes the assert to fail :
void process_batch(
string_vector & v
)
{
entry_vector sv;
training_entry te;
assert(sv.size() == 0);
...
}
Now I know this issue isn't shrink wrapped, so I'll restrict my question to this: what conditions could cause such a problem ? Specifically: variable initialization getting damaged dependant on appearance order in the stack frame. There are no malloc's or free's in my code, and no unsafe functions like strcpy, memcpy etc... it's modern c++. Compilers used: gcc and clang.
For brevity here are the type's
struct line_string
{
boost::uint32_t line_no;
std::string line;
};
typedef std::vector<boost::uint32_t> line_vector;
typedef std::vector<line_vector> entry_vector;
typedef std::vector<line_string> string_vector;
struct training_body
{
boost::uint32_t url_id;
bool relevant;
};
struct training_entry
{
boost::uint32_t session_id;
boost::uint32_t region_id;
std::vector< training_body> urls;
};
p.s., I am in no way saying that there is a issue in the compiler, it's probably my code. But since I am templatizing some code I wrote a long time ago, the issue has me completely stumped, I don't know where to look to find the problem.
edit
followed nim's suggestion and went through the following loop
shrink wrap the code to what I have shown here, compile and test, no problem.
#if 0 #endif to shrink wrap the main program.
remove headers till it compiles in shrink wrapped form.
remove library links till compiles in shrink wrapped form.
Solution: removing link to protocol buffers gets rid of the problem
The C++ standard guarantees that the following assertion will succeed:
std::vector<anything> Default;
//in your case anything is line_vector and Default is sv
assert(Default.size() == 0);
So, either you're not telling the whole story or you have a broken STL implementation.
OR: You have undefined behavior in your code. The C++ standard gives no guarantees about the behavior of a program which has a construct leading to UB, even prior to reaching that construct.
The usual case for this when one of the created objects writes beyond
its end in the constructor. And the most frequent reason this happens
in code I've seen is that object files have been compiled with different
versions of the header; e.g. at some point in time, you added (or
removed) a data member of one of the classes, and didn't recompile all
of the files which use it.
What might cause the sort of problem you see is a user-defined type with a misbehaving constructor;
class BrokenType {
public:
int i;
BrokenType() { this[1].i = 9999; } // Bug!
};
void process_batch(
string_vector & v
)
{
training_entry te;
BrokenType b; // bug in BrokenType shows up as assert fail in std::vector
entry_vector sv;
assert(sv.size() < 100);
...
}
Do you have the right version of the Boost libaries suited for your platform? (64 bit/32 bit)? I'm asking since the entry_vector object seems to be have a couple of member variables of type boost::uint32_t. I'm not sure what could be the behaviour if your executable is built for one platform and the boost library loaded is of another platform.