Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Newbie: bus error

Reply
Thread Tools

Newbie: bus error

 
 
David Kensche
Guest
Posts: n/a
 
      10-12-2004
Hello,
A bus error is caused every time I execute a method. I learned that bus
errors are usually caused if something is going wrong with memory
allocation and dereferencing. But I can't make out the error here.
Can anybody help?

Thanks beforehand,
David Kensche



int pc_record(char* key1, char* key2, record_t record) {
//cout << "pc_record(..): record = " << (int)record << "\n";
Logger *log = new Logger("TermCache.log");
string msg = "pc_record(";
// By the way, this is not very convenient, is there a way to ease
// this setup?
msg += key1;
msg += ", ";
msg += key2;
msg += "): ";
//msg = "pc_record(" + ", " + "): ";
//msg += string(key1) + ", " + string(key2) + "): ";
//msg += key1 + ", " + key2 + "): ";
// The following line causes the bus error.
log->debug(msg + "entered");
int solve = FAIL;
recordMap* cluster = &clusters[key2];
if(cluster->find(key1) == cluster->end()) {
cluster->insert(recordMap::value_type(key1, record));
solve = SUCCEED;
}

delete log;
return solve;
}


And this is the Logger class:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
using namespace std;

#define TRACE 0
#define DEBUG 1
#define INFO 2
#define WARN 3
#define FATAL 4

class Logger {

char* logfile;
int level;

public:
Logger(const char* file) {
level = TRACE;
logfile = (char*)malloc(strlen(getenv("HOME")) + 1 + strlen(file));
//free(logfile);
strcpy(logfile, getenv("HOME"));
strcat(logfile, "/");
strcat(logfile, file);
}

void setLevel(int logLevel) {
level = logLevel;
}

void trace(string msg) {
if(level <= TRACE) {
std:fstream out;
out.open(logfile, ios_base:ut | ios_base::app);
out << "TRACE:" << msg << "\n";
out.close();
}
}

void debug(string msg) {
if(level <= DEBUG) {
std:fstream out;
out.open(logfile, ios_base:ut | ios_base::app);
out << "DEBUG:" << msg << "\n";
out.close();
}
}

void info(string msg) {
if(level <= INFO) {
std:fstream out;
out.open(logfile, ios_base:ut | ios_base::app);
out << "INFO:" << msg << "\n";
out.close();
}
}

void warn(string msg) {
if(level <= WARN) {
std:fstream out;
out.open(logfile, ios_base:ut | ios_base::app);
out << "WARN:" << msg << "\n";
out.close();
}
}

void fatal(string msg) {
if(level <= FATAL) {
std:fstream out;
out.open(logfile, ios_base:ut | ios_base::app);
out << "FATAL:" << msg << "\n";
out.close();
}
}

private:
void operator=(const Logger&);
void operator&();
void operator,(const Logger&);
};

 
Reply With Quote
 
 
 
 
John Harrison
Guest
Posts: n/a
 
      10-12-2004

"David Kensche" <(E-Mail Removed)-aachen.de> wrote in message
news:(E-Mail Removed)...
> Hello,
> A bus error is caused every time I execute a method. I learned that bus
> errors are usually caused if something is going wrong with memory
> allocation and dereferencing. But I can't make out the error here.
> Can anybody help?


See below.

>
> Thanks beforehand,
> David Kensche
>
>
>
> int pc_record(char* key1, char* key2, record_t record) {
> //cout << "pc_record(..): record = " << (int)record << "\n";
> Logger *log = new Logger("TermCache.log");
> string msg = "pc_record(";
> // By the way, this is not very convenient, is there a way to ease
> // this setup?
> msg += key1;
> msg += ", ";
> msg += key2;
> msg += "): ";
> //msg = "pc_record(" + ", " + "): ";
> //msg += string(key1) + ", " + string(key2) + "): ";
> //msg += key1 + ", " + key2 + "): ";


This is perhaps a bit easier (and clearer)

ostringstream buffer;
buffer << "pc_record(" << key1 << ", " << key2 << "): ";
string msg = buffer.str();

> // The following line causes the bus error.
> log->debug(msg + "entered");
> int solve = FAIL;
> recordMap* cluster = &clusters[key2];
> if(cluster->find(key1) == cluster->end()) {
> cluster->insert(recordMap::value_type(key1, record));
> solve = SUCCEED;
> }
>
> delete log;
> return solve;
> }
>
>
> And this is the Logger class:
> #include <iostream>
> #include <fstream>
> #include <cstdlib>
> #include <string>
> using namespace std;
>
> #define TRACE 0
> #define DEBUG 1
> #define INFO 2
> #define WARN 3
> #define FATAL 4
>
> class Logger {
>
> char* logfile;
> int level;
>
> public:
> Logger(const char* file) {
> level = TRACE;
> logfile = (char*)malloc(strlen(getenv("HOME")) + 1 + strlen(file));
> //free(logfile);
> strcpy(logfile, getenv("HOME"));
> strcat(logfile, "/");
> strcat(logfile, file);
> }


One error is here, you need to malloc one more byte (length of HOME, length
of file, length of "/", plus one for terminating nul )

logfile = (char*)malloc(strlen(getenv("HOME")) + 2 + strlen(file));

And the moral is don't use C strings, use C++ strings.

john


 
Reply With Quote
 
 
 
 
John Harrison
Guest
Posts: n/a
 
      10-12-2004
> This is perhaps a bit easier (and clearer)
>
> ostringstream buffer;
> buffer << "pc_record(" << key1 << ", " << key2 << "): ";
> string msg = buffer.str();
>


You need the header file <sstream> for the ostringstream class.

john


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      10-12-2004
David Kensche wrote:
> Hello,
> A bus error is caused every time I execute a method. I learned that bus
> errors are usually caused if something is going wrong with memory
> allocation and dereferencing. But I can't make out the error here.
> Can anybody help?
>
> Thanks beforehand,
> David Kensche
>
>
>
> int pc_record(char* key1, char* key2, record_t record) {


Why 'key1' and 'key2' are not pointers to const char?

> //cout << "pc_record(..): record = " << (int)record << "\n";
> Logger *log = new Logger("TermCache.log");


Why do you need 'log' dynamically allocated here? Why can't you just
write

Logger log("TermCache.log");

? No need to delete, no problems with dynamic memory...

> string msg = "pc_record(";
> // By the way, this is not very convenient, is there a way to ease
> // this setup?


What setup? What's not very convenient?

> msg += key1;
> msg += ", ";
> msg += key2;
> msg += "): ";
> //msg = "pc_record(" + ", " + "): ";
> //msg += string(key1) + ", " + string(key2) + "): ";
> //msg += key1 + ", " + key2 + "): ";
> // The following line causes the bus error.
> log->debug(msg + "entered");
> int solve = FAIL;
> recordMap* cluster = &clusters[key2];
> if(cluster->find(key1) == cluster->end()) {
> cluster->insert(recordMap::value_type(key1, record));
> solve = SUCCEED;
> }
>
> delete log;
> return solve;
> }
>
>
> And this is the Logger class:
> #include <iostream>
> #include <fstream>
> #include <cstdlib>
> #include <string>
> using namespace std;
>
> #define TRACE 0
> #define DEBUG 1
> #define INFO 2
> #define WARN 3
> #define FATAL 4
>
> class Logger {
>
> char* logfile;


Drop the 'char*', use std::string.

> int level;
>
> public:
> Logger(const char* file) {
> level = TRACE;
> logfile = (char*)malloc(strlen(getenv("HOME")) + 1 + strlen(file));
> //free(logfile);
> strcpy(logfile, getenv("HOME"));
> strcat(logfile, "/");
> strcat(logfile, file);


Now, count the allocated characters. Where should the terminating \0 go?

Once again, replace all the dynamic memory nonsense with std::string.
You will be rid of all memory errors at once. Of course, you'll have
to change _every_

out.open(logfile,
to
out.open(logfile.c_str(),

but is that such a big deal?

> }
>
> void setLevel(int logLevel) {
> level = logLevel;
> }
>
> void trace(string msg) {
> if(level <= TRACE) {
> std:fstream out;
> out.open(logfile, ios_base:ut | ios_base::app);


'logfile' here is malformed.

> out << "TRACE:" << msg << "\n";
> out.close();
> }
> }
>
> void debug(string msg) {
> if(level <= DEBUG) {
> std:fstream out;
> out.open(logfile, ios_base:ut | ios_base::app);


'logfile' here is malformed.

> out << "DEBUG:" << msg << "\n";
> out.close();
> }
> }
>
> void info(string msg) {
> if(level <= INFO) {
> std:fstream out;
> out.open(logfile, ios_base:ut | ios_base::app);


'logfile' here is malformed.

> out << "INFO:" << msg << "\n";
> out.close();
> }
> }
>
> void warn(string msg) {
> if(level <= WARN) {
> std:fstream out;
> out.open(logfile, ios_base:ut | ios_base::app);


'logfile' here is malformed.

> out << "WARN:" << msg << "\n";
> out.close();
> }
> }
>
> void fatal(string msg) {
> if(level <= FATAL) {
> std:fstream out;
> out.open(logfile, ios_base:ut | ios_base::app);


'logfile' here is malformed.

> out << "FATAL:" << msg << "\n";
> out.close();
> }
> }
>
> private:
> void operator=(const Logger&);
> void operator&();
> void operator,(const Logger&);
> };
>


I don't understand why beginners can't help themselves and try to always
use "new" or "malloc". Don't! There is no need for that in your program.

Victor
 
Reply With Quote
 
Peter van Merkerk
Guest
Posts: n/a
 
      10-12-2004
John and Victor have already pointed out problems in your code and gave
you excellent advice. But there is another potential problem in your code:

> class Logger {
>
> char* logfile;
> int level;
>
> public:
> Logger(const char* file) {
> level = TRACE;
> logfile = (char*)malloc(strlen(getenv("HOME")) + 1 + strlen(file



If the HOME environment variable does not exist getenv() will return
NULL. Nasty things can happen when you pass a NULL pointer to strlen().

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl
 
Reply With Quote
 
David Kensche
Guest
Posts: n/a
 
      10-12-2004
Thank you for all the hints, but it doesn't work yet.
I replaced as much char* by string as I could, but to
client modules (from C) this class has to look like C,
and this is the reason why I need char* in the interface.
The situation even worsened. Now I even do not need to
create the Logger to cause a "bus error".
My new source code looks like this:


#include <map>
#include <stdlib.h>
#include <iostream>
#include "TermCache.h"
#include "prolog.h"
#include "Logger.cc"
using namespace std;

typedef map<string, record_t> recordMap;
typedef map<string, recordMap > clusterMap;

class TermCache {
clusterMap clusters;

public:

/**
* Stores a copy of the PROLOG_TERM 'record' associated to
* double key (key1, key2). Fails with an error if there
* is already a value associated to the double key.
*/
int pc_record(char* key1, char* key2, record_t record) {
string k1 = string(key1);
string k2 = string(key2);
// As you can see now I have the Logger commented. But nevertheless
// a bus error is caused by something.
//Logger log(string("TermCache.log"));
ostringstream buffer;
buffer << "pc_record(" << k1 << ", " << k2 << "): ";
string msg = buffer.str();
//log.debug(msg + "entered");
int solve = FAIL;
recordMap* cluster = &clusters[k2];
if(cluster->find(k1) == cluster->end()) {
cluster->insert(recordMap::value_type(k1, record));
solve = SUCCEED;
}
return solve;
}

/**
* Stores a copy of the PROLOG_TERM 'record' associated to
* double key (key1, key2). Any value that was associated
* to the double key, is erased.
*/
int pc_rerecord(char* key1, char* key2, record_t record) {
string k1 = string(key1);
string k2 = string(key2);
recordMap* cluster = &clusters[k2];
//cout << "pc_rerecord(..): Fetch iterator on key1-Element\n";
recordMap::iterator oldRecord = cluster->find(k1);
//cout << "pc_rerecord(..): oldRecord != cluster->end():" <<
(oldRecord != cluster->end()) << "\n";
if(oldRecord == cluster->end()) {
cluster->insert(recordMap::value_type(k1, record));
} else {
oldRecord->second = record;
}
//cout << "pc_rerecord(..): return\n";
return SUCCEED;
}

....
};

/************************************************** ***********************/
/* C implementation of TermCache.h passes calls to cpp TermCache object. */
/************************************************** ***********************/

static TermCache tc;

// SWI: In: foreign_t Out: record_t
// BIM: In: 0, 1 Out: C-Datentypen
int pc_record(char* key1, char* key2, record_t record) {
return tc.pc_record(key1, key2, record);
}

int pc_rerecord(char* key1, char* key2, record_t record) {
return tc.pc_rerecord(key1, key2, record);
}

int pc_recorded(char* key1, char* key2, record_t* record) {
return tc.pc_recorded(key1, key2, record);
}

int pc_is_a_key(char* key1, char* key2) {
return tc.pc_is_a_key(key1, key2);
}

int pc_erase(char* key1, char* key2) {
return tc.pc_erase(key1, key2);
}

int pc_erase_all(char* key2) {
return tc.pc_erase_all(key2);
}

int pc_current_key(char* key1, char* key2, PROLOG_TERM* resultList) {
return tc.pc_current_key(key1, key2, resultList);
}


Logger:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <sstream>
using namespace std;

#define TRACE 0
#define DEBUG 1
#define INFO 2
#define WARN 3
#define FATAL 4

class Logger {

string logfile;
int level;

public:
Logger(string file) {
level = TRACE;
logfile = getenv("HOME");
logfile += "/";
logfile += file;
// value at this point is logfile == "/home/kensche/TermCache.log"
}

void setLevel(int logLevel) {
level = logLevel;
}

void trace(string msg) {
if(level <= TRACE) {
std:fstream out;
out.open(logfile.c_str(), ios_base:ut | ios_base::app);
out << "TRACE:" << msg << "\n";
out.close();
}
}

void debug(string msg) {
if(level <= DEBUG) {
std:fstream out;
out.open(logfile.c_str(), ios_base:ut | ios_base::app);
out << "DEBUG:" << msg << "\n";
out.close();
}
}

void info(string msg) {
if(level <= INFO) {
std:fstream out;
out.open(logfile.c_str(), ios_base:ut | ios_base::app);
out << "INFO:" << msg << "\n";
out.close();
}
}

void warn(string msg) {
if(level <= WARN) {
std:fstream out;
out.open(logfile.c_str(), ios_base:ut | ios_base::app);
out << "WARN:" << msg << "\n";
out.close();
}
}

void fatal(string msg) {
if(level <= FATAL) {
std:fstream out;
out.open(logfile.c_str(), ios_base:ut | ios_base::app);
out << "FATAL:" << msg << "\n";
out.close();
}
}

private:
void operator=(const Logger&);
void operator&();
void operator,(const Logger&);
};


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      10-12-2004
David Kensche wrote:
> Thank you for all the hints, but it doesn't work yet.
> I replaced as much char* by string as I could, but to
> client modules (from C) this class has to look like C,
> and this is the reason why I need char* in the interface.
> The situation even worsened. Now I even do not need to
> create the Logger to cause a "bus error".
> My new source code looks like this:
>
> [...]


Whatever the problem is, it's not in the "Logger" any longer.
The presented source code is incomplete and causes making some
assumptions that render any advice impossible.

Debug your program. That's what we all do when we have similar
problems. Compile it with debugging information in, run it under
the debugger, see where it breaks. Look at variables, analyse
the call stack... You know, programming is not just writing code.

V
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      10-12-2004

"David Kensche" <(E-Mail Removed)-aachen.de> wrote in message
news:(E-Mail Removed)...
> Thank you for all the hints, but it doesn't work yet.
> I replaced as much char* by string as I could, but to
> client modules (from C) this class has to look like C,
> and this is the reason why I need char* in the interface.
> The situation even worsened. Now I even do not need to
> create the Logger to cause a "bus error".
> My new source code looks like this:
>


Are you sure that the pointers being passed into your code are correct?

I couldn't see anything wrong in the posted code.

john


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Address Bus and External Data Bus Confusion LoXodonte A+ Certification 1 04-18-2006 09:09 PM
AS5350: Main Memory Write Bus Error Interrupt Слава Чернов Cisco 1 07-23-2004 09:40 PM
bus error with printf line included, error without printf line? ben C Programming 4 06-26-2004 04:42 PM
1600 reboot - bus error? Phil Cisco 3 02-24-2004 11:09 AM
Urgent help pleeeeassse... System restarted by bus error ReD-MaN Cisco 3 12-30-2003 11:03 PM



Advertisments