Segmentation fault in constructor in c++ - c++

So I have the cl_Page class:
class cl_Page{
public:
cl_Page(cl_LessonMoment *parent_param);
cl_Page(cl_SoftRoot *parent_param);
int parent_type;
cl_LessonMoment *parent_lmoment;
cl_SoftRoot *parent_softroot;
char id[256];
//<content>
//Backgrounds.
str_Color bgcolor;
cl_Image bgimage;
//Actual content
vector<cl_Textbox> textboxes;
vector<cl_Button> buttons;
vector<cl_Image> images;
//</content>
cl_Textbox* AddTextbox();
cl_Button* AddButton();
cl_Image* AddImage(char *filename = nullptr);
};
and the cl_Page constructors:
cl_Page::cl_Page(cl_LessonMoment *parent_param) : bgimage(nullptr){ //here is the segfault
parent_lmoment = parent_param;
parent_type = 1;
id[0] = '\0';
SetColor(bgcolor, 0xffffffff);
}
cl_Page::cl_Page(cl_SoftRoot *parent_param): bgimage(nullptr){ // or here if i call this constructor
/*parent_softroot = parent_param;
parent_type = 2;
id[0] = '\0';
SetColor(bgcolor, 0xffffffff);*/
}
What happens is that, no matter how I call the constructors, or no matter which one I call (the second is all commented out; so basically empty), global, local or dynamically, in a function or as a member object, I get a segmentation fault which appears to be right on the cl_Page::cl_Page(cl_LessonMoment *parent_param) : bgimage(nullptr){ line. The call stack looks like this:
#0 77C460CB strcat() (C:\WINDOWS\system32\msvcrt.dll:??)
#1 0022F168 ?? () (??:??)
#2 00401905 cl_Page::cl_Page(this=0x22fbe8, parent_param=0x0) (F:\Scoala\C++\EduSoftViewer_Parser\sources\classes\soft_tree\page.cpp:10)
#3 00402B8A main() (F:\Scoala\C++\EduSoftViewer_Parser\sources\main.cpp:11)
On some builds before I am writing this, (with exactly the same issue) the #1 position on the call stack, where now is ?? () (??:??) was ntdll!RtlDosApplyFileIsolationRedirection_Ustr() (C:\WINDOWS\system32\ntdll.dll:??).
So my question is: Does anybody know what is causing this? I really need to get this working.
If anything is unclear, just ask and I'll provide additional information.
EDIT: To clarify: I'm under Windows XP SP2 and running Code::Blocks with gcc.
EDIT 2: The cl_Image constructor:
cl_Image::cl_Image(char *filename_param){
if (filename == nullptr){
filename[0] = '\0';
}
else{
strcpy(filename, filename_param);
}
SetPosition(position, 0, 0);
id[0] = '\0';
visible = 1;
z_index = 0;
}
This class doesn't contain any object members, with the exception of a POD struct, position
EDIT 3: The cl_Image class:
class cl_Image{
public:
cl_Image(char* filename_param = nullptr);
str_Position position;
char filename[256];
char id[256];
bool visible;
int z_index;
};
str_Position is just a struct of 2 ints.

Pretty sure this is your problem:
cl_Image::cl_Image(char *filename_param){
if (filename == nullptr){ // <<==== filename??? try using the param.
filename[0] = '\0';
}
Try this:
cl_Image::cl_Image(char *filename_param){
if (filename_param == nullptr){
filename[0] = '\0';
}

I'll guess that bgimage can't be initialized with nullptr.

Related

Damaged heap while working with dynamically allocated variables and _chdir windows function

while working with those function i'm getting stuck with an error.
The debbuger says "damged heap" on _chdir(dirCorrente); line.
The main calls those function as follow:
- char* temp = getCartellaCorrente();
- some other stuff not relative to these function...
- temp = setCartellaCorrente("cd test")
when the execution stops the setCartellaCorrente's dirCorrente value is '"C:\Users\Luca\Desktop\remote-control-project\FirstService\Debug\test"'
I think i'm doing something wrong with dynamically allocated variables.
I'm working on this problem since 48 hours now, i've serached on the internet but nothing. I guess that i don't know something important about allocated variable or _chdir function.
I will be really gratefull if you can explain me what i miss.
char* getCartellaCorrente() {
char* temp;
size_t size;
LPWSTR dirCorrente = new TCHAR[DEFAULT_BUFLEN];
GetCurrentDirectory(DEFAULT_BUFLEN, dirCorrente);
size = wcslen(dirCorrente);
temp = (char *)malloc(size);
wcstombs_s(NULL, temp, size+1, dirCorrente, size);
return temp;
}
char* setCartellaCorrente(char* relative) {
char *dirCorrente;
if (strlen(relative)>=5 && relative[4] == ':') {
dirCorrente = (char *)malloc(DEFAULT_BUFLEN);
strcpy_s(dirCorrente, DEFAULT_BUFLEN, &relative[3]);
}
else {
dirCorrente = getCartellaCorrente();
relative[2] = '\\';
strcat_s(dirCorrente, DEFAULT_BUFLEN, &relative[2]);
printf("goode %s \n", dirCorrente);
}
//fixPathSlash(dirCorrente);
printf("\n2: %s\n", dirCorrente);
int i = _chdir(dirCorrente); //HERE IT STOPS
printf("wtf: %d\n", i);
free(dirCorrente);
printf("boh\n");
return getCartellaCorrente();
}
It's my first question. Sorry if i missed some important information, i'll edit fast.
Ok i managed to solve the problem, as i thoght the problem was the allocation.
Since i need to solve this fast for now i've used the method i listed above, anyway i will study how to work with allocated variable and modify it to improve it.
void getCartellaCorrente(char* temp) {
size_t size;
LPWSTR dirCorrente = new TCHAR[DEFAULT_BUFLEN];
GetCurrentDirectory(DEFAULT_BUFLEN, dirCorrente);
size = wcslen(dirCorrente);
wcstombs_s(NULL, temp, DEFAULT_BUFLEN, dirCorrente, size);
}
void setCartellaCorrente(char* relative, char* dirCorrente) {
if (strlen(relative)>=5 && relative[4] == ':') {
strcpy_s(dirCorrente, DEFAULT_BUFLEN, &relative[3]);
}
else {
getCartellaCorrente(dirCorrente);
relative[2] = '\\';
strcat_s(dirCorrente, DEFAULT_BUFLEN, &relative[2]);
}
int i = _chdir(dirCorrente);
return getCartellaCorrente(dirCorrente);
}
The path variable is now allocated into the main with static size, the functions does not return the correct value, instead they change it directly.

std::queue bug? pop calls to wrong destroy function

I'm working with C++ queues. First, I make a push (the copy constructor is called and works fine) and when I do a simple pop, it calls the first destructor method (not the new created). Here a sample code:
{
T_MENSAJE new_msg; // Constructor 1 called -> Instance 1
new_msg.rellena(msg);
m_messages.push(new_msg); // Copy constructor called -> Instance 2
m_messages.pop(); // Destructor of instance 1 called !!!!!!!
return; // again, destructor of instance 1 called
}
Edit:
For demonstrate it, I show the memory direction of m_data, into rellena(msg); constructor copy method and in the destroyer. In rellena, has memDir1, in copy constructor memDir2, as I expectyed. But when I call pop method, the destroyer method shows memDir1 (not memDir2 as I expected), then when the function finish, the destroyer is called again and memDir1 is shown again. Here is the T_MENSAJE struct:
typedef struct T_MENSAJE
{
T_MSG_HEADER m_cab;
char m_command[MSG_COMMAND_SIZE];
char* m_data;
T_MENSAJE():m_data(0){
}
~T_MENSAJE()
{
static int counter = 0;
if (m_data != 0)
{
printf("%s -- direction = %d\n",__FUNCTION__,m_data);
delete[](m_data);
}
}
T_MENSAJE(const T_MENSAJE& m)
{
m_cab = m.m_cab;
memcpy(&m_command,&m.m_command,MSG_COMMAND_SIZE);
if (m.m_data != 0)
{
int numBytes = m_cab.m_lenght-MSG_HEADER_SIZE-MSG_COMMAND_SIZE;
m_data = new char[numBytes];
printf("%s -- direction = %d\n",__FUNCTION__,m_data);
memcpy((char*)&(m_data),&m.m_data, numBytes);
}else
{
m_data = 0;
}
}
......
......
......
}
The memcpy memcpy((char*)&(m_data),&m.m_data, numBytes); copies numBytes from the address of &m.m_data to the address of your member m_data. This is wrong and overwrites parts of your object.

Initialize pid_t variable

I have an error reported by Valgrind:
==5644== Conditional jump or move depends on uninitialised value(s)
This is happening for a variable of type pid_t.
My code is the following:
GmpPipePlayer::GmpPipePlayer( IOBase *pIO, Referee *pBack, PieceColor pc, int size, const DataBoard *pBd, int handicap, const char *cmd_line, int bDebug )
: GmpPlayer(pIO, pBack, pc, size, pBd, handicap, bDebug)
{
int down[2], up[2];
pid_t _pid; //here the var is declared
pipe(down);
pipe(up);
_pid = fork();
if (_pid < 0)
exit(1);
if (_pid == 0)
{
close(down[1]);
close(up[0]);
dup2(down[0], 0);
dup2(up[1], 1);
execl("/bin/sh", "sh", "-c", cmd_line, NULL);
_exit(1);
}
close(down[0]);
close(up[1]);
_down = down[1];
_up = up[0];
_reader_thd = new Thread(reader_wrapper, this);
}
GmpPipePlayer::~GmpPipePlayer()
{
if (_pid > 0) //valgrind is reporting that the error is here!!
{
kill(_pid, SIGTERM);
_pid = 0;
}
if (_up)
{
close(_up);
_up = 0;
}
if (_down)
{
close(_down);
_down = 0;
}
delete _reader_thd
}
So, I think the problem is the _pid is not initialized, how should initialize this variable? I tried in this way:
pid_t _pid=0;
but this is still causing the same error. That piece of code is called many times during the process.
It appears that you have two variables called _pid - the local that you declared in the constructor:
pid_t _pid; //here the var is declared
and the one that you access in the destructor:
if (_pid > 0) //valgrind is reporting that the error is here!!
These variables are not the same: the one that you access in the destructor must be a global or an instance variable (more likely).
Since you rely on _pid to pass the state from the constructor to the destructor, you need to remove the local declaration from the constructor, and initialize the other _pid as appropriate. If it is an instance variable, add its initialization to the initializer list, like this:
GmpPipePlayer::GmpPipePlayer( IOBase *pIO, Referee *pBack, PieceColor pc, int size, const DataBoard *pBd, int handicap, const char *cmd_line, int bDebug )
: GmpPlayer(pIO, pBack, pc, size, pBd, handicap, bDebug), _pid(0) {
... // HERE ------------------^
}

Function has corrupt return value

I have a situation in Visual C++ 2008 that I have not seen before. I have a class with 4 STL objects (list and vector to be precise) and integers.
It has a method:
inline int id() { return m_id; }
The return value from this method is corrupt, and I have no idea why.
debugger screenshot http://img687.imageshack.us/img687/6728/returnvalue.png
I'd like to believe its a stack smash, but as far as I know, I have no buffer over-runs or allocation issues.
Some more observations
Here's something that puts me off. The debugger prints right values in the place mentioned // wrong ID.
m_header = new DnsHeader();
assert(_CrtCheckMemory());
if (m_header->init(bytes, size))
{
eprintf("0The header ID is %d\n", m_header->id()); // wrong ID!!!
inside m_header->init()
m_qdcount = ntohs(h->qdcount);
m_ancount = ntohs(h->ancount);
m_nscount = ntohs(h->nscount);
m_arcount = ntohs(h->arcount);
eprintf("The details are %d,%d,%d,%d\n", m_qdcount, m_ancount, m_nscount, m_arcount);
// copy the flags
// this doesn't work with a bitfield struct :(
// memcpy(&m_flags, bytes + 2, sizeof(m_flags));
//unpack_flags(bytes + 2); //TODO
m_init = true;
}
eprintf("Assigning an id of %d\n", m_id); // Correct ID.
return
m_header->id() is an inline function in the header file
inline int id() { return m_id; }
I don't really know how best to post the code snippets I have , but here's my best shot at it. Please do let me know if they are insufficient:
Class DnsHeader has an object m_header inside DnsPacket.
Main body:
DnsPacket *p ;
p = new DnsPacket(r);
assert (_CrtCheckMemory());
p->add_bytes(buf, r); // add bytes to a vector m_bytes inside DnsPacket
if (p->parse())
{
read_packet(sin, *p);
}
p->parse:
size_t size = m_bytes.size(); // m_bytes is a vector
unsigned char *bytes = new u_char[m_bytes.size()];
copy(m_bytes.begin(), m_bytes.end(), bytes);
m_header = new DnsHeader();
eprintf("m_header allocated at %x\n", m_header);
assert(_CrtCheckMemory());
if (m_header->init(bytes, size)) // just set the ID and a bunch of other ints here.
{
size_t pos = DnsHeader::SIZE; // const int
if (pos != size)
; // XXX perhaps generate a warning about extraneous data?
if (ok)
m_parsed = true;
}
else
{
m_parsed = false;
}
if (!ok) {
m_parsed = false;
}
return m_parsed;
}
read_packet:
DnsHeader& h = p.header();
eprintf("The header ID is %d\n", h.id()); // ID is wrong here
...
DnsHeader constructor:
m_id = -1;
m_qdcount = m_ancount = m_nscount = m_arcount = 0;
memset(&m_flags, 0, sizeof(m_flags)); // m_flags is a struct
m_flags.rd = 1;
p.header():
return *m_header;
m_header->init: (u_char* bytes, int size)
header_fmt *h = (header_fmt *)bytes;
m_id = ntohs(h->id);
eprintf("Assigning an id of %d/%d\n", ntohs(h->id), m_id); // ID is correct here
m_qdcount = ntohs(h->qdcount);
m_ancount = ntohs(h->ancount);
m_nscount = ntohs(h->nscount);
m_arcount = ntohs(h->arcount);
You seem to be using a pointer to an invalid class somehow. The return value shown is the value that VS usually uses to initialize memory with:
2^32 - 842150451 = 0xCDCDCDCD
You probably have not initialized the class that this function is a member of.
Without seeing more of the code in context.. it might be that the m_id is out of the scope you expect it to be in.
Reinstalled VC++. That fixed everything.
Thank you for your time and support everybody! :) Appreciate it!

Valgrind reports "Invalid free() / delete / delete[]"

I'm not sure what could be causing this.
==18270== Invalid free() / delete / delete[]
==18270== at 0x400576A: operator delete(void*) (vg_replace_malloc.c:342)
==18270== by 0x80537F7: LCD::LCDControl::~LCDControl() (LCDControl.cpp:23)
==18270== by 0x806C055: main (Main.cpp:22)
==18270== Address 0x59e92c4 is 388 bytes inside a block of size 712 alloc'd
==18270== at 0x40068AD: operator new(unsigned int) (vg_replace_malloc.c:224)
==18270== by 0x8078033: LCD::DrvCrystalfontz::Get(std::string, LCD::LCDControl*, Json::Value*, std::string) (DrvCrystalfontz.cpp:652)
==18270== by 0x8053F50: LCD::LCDControl::ConfigSetup() (LCDControl.cpp:71)
==18270== by 0x80539F7: LCD::LCDControl::Start(int, char**) (LCDControl.cpp:31)
==18270== by 0x806C025: main (Main.cpp:21)
Here's LCDControl's destructor where delete is called.
LCDControl::~LCDControl() {
Shutdown();
for(std::vector<std::string>::iterator it = display_keys_.begin();
it != display_keys_.end(); it++) {
Error("Deleting %s %p", (*it).c_str(), devices_text_[*it]);
if(devices_text_.find(*it) != devices_text_.end() && devices_text_[*it])
delete devices_text_[*it]; // line 23
}
//delete app_;
}
Here's Crystalfontz::Get()
switch(m->GetProtocol()) {
case 1:
return new Protocol1(name, m, v, config);
break;
case 2:
return new Protocol2(name, m, v, config); // line 652
break;
case 3:
return new Protocol3(name, m, v, config, scab);
break;
default:
Error("Internal error. Model has bad protocol: <%s>",
m->GetName().c_str());
break;
devices_text_:
std::map<std::string, Generic <LCDText>*> devices_text_;
LCDControl::ConfigSetup(),
void LCDControl::ConfigSetup() {
if(!CFG_Get_Root()) return;
Json::Value::Members keys = CFG_Get_Root()->getMemberNames();
for(std::vector<std::string>::iterator it = keys.begin(); it != keys.end(); it++ ) {
if(it->find("display_", 0) != std::string::npos) {
Json::Value *display = CFG_Fetch_Raw(CFG_Get_Root(), it->c_str());
Json::Value *driver = CFG_Fetch_Raw(display, "driver");
if(!driver) {
Error("CFG: Must specify driver <%s>", it->c_str());
continue;
}
Json::Value *rows = CFG_Fetch_Raw(display, "rows", new Json::Value(-1));
/*if(!rows->isNumeric() || rows->asInt() == -1) {
Error("Display <%s> requires number of rows to initialize.", it->c_str());
delete display;
delete driver;
continue;
}*/
Json::Value *cols = CFG_Fetch_Raw(display, "cols", new Json::Value(-1));
/*if(!cols->isNumeric() || rows->asInt() == -1) {
Error("Display <%s> requires number of columns to initialize.", it->c_str());
delete display;
delete driver;
delete rows;
continue;
}*/
Json::Value *model = CFG_Fetch_Raw(display, "model");
if(driver->asString() == "crystalfontz") {
if(model) {
devices_text_[*it] = DrvCrystalfontz::Get(*it, this,
CFG_Get_Root(), model->asString()); // line 71
} else {
Error("Device <%s> requires a model.", it->c_str());
delete display;
delete driver;
delete rows;
delete cols;
continue;
}
} else if(driver->asString() == "qt") {
devices_text_[*it] = new DrvQt(*it, this, CFG_Get_Root(),
rows->asInt(), cols->asInt());
} else if(driver->asString() == "pertelian") {
//devices_text_[*it] = new DrvPertelian(this, CFG_Get_Root(), rows->asInt(), cols->asInt());
} else
continue;
if(model) delete model;
delete display;
delete driver;
delete rows;
delete cols;
}
}
for(std::map<std::string, Generic<LCDText> *>::iterator it =
devices_text_.begin(); it != devices_text_.end(); it++) {
display_keys_.push_back(it->first);
Error("Starting <%s> %p", it->first.c_str(), it->second);
Generic<LCDText> *device = it->second;
device->CFGSetup(it->first);
device->Connect();
device->SetupDevice();
device->BuildLayouts();
device->StartLayout();
}
}
I'm guessing that Protocol1 et al. are subclasses of some SuperProtocol?
devices_text_[*it] goes through assuming that it contains something of type SuperProtocol, so delete devices_text_[*it] calls SuperProtocol::~ SuperProtocol().
However, what you really want to call is Protocol1::~Protocol1() if you're destructing a Protocol1; this only works if you mark SuperProtocol::~ SuperProtocol() as virtual.
Instead of going through the keys, finding it in the map, then deleting it, why not just iterate through the map deleting as you go? I'd make a functor and use for_each (this isn't a guideline or anything, just my opinion),
typedef Generic<LCDText> GenericLCDText;
typedef std::map<std::string, GenericLCDText*> GenericLCDTextMap;
typedef GenericLCDTextMap::value_type GenericLCDTextPair;
struct device_text_deleter : std::unary_function<const GenericLCDTextPair&, void>
{
void operator()(const GenericLCDTextPair& pPair)
{
Error("Deleting %s %p", pPair.first.c_str(), pPair.second);
delete pPair.second;
}
}
std::for_each(devices_text_.begin(), devices_text_.end(), device_text_deleter());
_devices.text_.clear(); // optional, removes the deleted pointers. unnecessary
// if this is run in the destructor, since map goes away
// shortly after
That said, you're code would be improved by the following:
// typedef's for readability (would be in header, maybe private)
typedef std::vector<std::string> StringVector;
typedef Generic<LCDText> GenericLCDText;
typedef std::map<std::string, GenericLCDText*> GenericLCDTextMap;
for(StringVector::iterator it = display_keys_.begin();
it != display_keys_.end(); it++)
{
// find first! otherwise you're looking up the pair every time
GenericLCDTextMap::iterator pair = devices_text_.find(*it);
if (p != devices_text_.end())
{
// operator-> is overloaded for iterators but might as well use
// the pair now.
Error("Deleting %s %p", pair->first.c_str(), pair->second);
// no need to check for null, delete null is a-ok
delete pair->second;
}
}
Hopefully this will make it easier to spot the errors. Make sure any base classes you use have virtual destructors.
Check you haven't added a string in the vector twice (this would be "fixed" buy just iterating through the map, though you'll want to find out why duplicates exist in the first place), etc.
I've never tried this before, but maybe add a double delete macro thing (totally untested):
#define DOUBLE_DELETE_GAURD static bool x = false; assert(x == false); x = true;
Then just add it to your destructor. If you double delete, and the static bool is still around, the assertion will fail. This is completely in undefined la-la land, though.
Could it be that
display_keys_ contains the same string more than once and
this string has an associated Generic <LCDText>* in devices_text_?
In this case the pointer would be given to delete twice and this isn't legal...