I have gone through stackoverflow questions similar to "Why is the destructor called twice?". My question can be a similar one but with a small change. I am getting an error when running the following code:
struct Employee{
char *name;
char *tag;
Employee *employee;
Employee(){
name = NULL;
tag = NULL;
employee = NULL;
}
//copy constructor
Employee(const Employee &obj){
cout << "Copy constructor called" << endl;
name = (char*)malloc(sizeof(char)*strlen(obj.name));
strcpy(name, obj.name);
tag = (char*)malloc(sizeof(char)*strlen(obj.tag));
strcpy(tag, obj.tag);
employee = (struct Employee*)malloc(sizeof(obj.employee));
employee = obj.employee;
}
//overloaded assignment operator
void operator = (const Employee &obj){
cout << "Assignment operator called" << endl;
if (this == &obj){
return;
}
strcpy(name, obj.name);
strcpy(tag, obj.tag);
employee = obj.employee;
}
//destructor
~Employee(){
cout << "Destructor called" << endl;
if (name != NULL){
cout << "Freeing name" << endl;
free(name);
name = NULL;
}
if (tag != NULL){
cout << "Freeing tag" << endl;
free(tag);
tag = NULL;
}
if (employee != NULL){
cout << "Freeing employee" << endl;
free(employee);
employee = NULL;
}
}
};
Employee createNode(){
Employee emp;
emp.name = (char*)malloc(sizeof(char)* 25);
strcpy(emp.name, "Alan");
emp.tag = (char*)malloc(sizeof(char)* 25);
strcpy(emp.tag, "Engineer");
emp.employee = (struct Employee*)malloc(sizeof(struct Employee));//just created memory, no initialization
return emp;
}
Employee get(){
//Employee emp = createNode();
//return emp;
return createNode();
}
int main(){
Employee emp = get();
getchar();
return 0;
}
I debugged the code and found that error is raising when the destructor is called second time when the main function exits.
1) I want to know why the code fails to run?
2) Are there any memory leaks?
3) How can I fix the error properly deallocating memory?
Thanks in advance.
Update:
As per the three Rule I have also added a copy constructor and overloaded the assignment operator. But the error(Expression : _crtisvalidheappointer(puserdata)) is raising. After checking in the Google I could see that some where the Heap corruption is happening. When I comment the initialization of the Struct member employee in the createNode() then I could see the error raising when trying to free the employee in destructor. So I suspect the problem is with the employee struct member. Please help me with this.I am using Visual studio for debugging and running.
Your problem is a lack of copy construct and assignment operator in your class. As a result you are freeing the strings within the class multiple times.
Just tried your code and found out a few issues that causes a crash:
1) strlen returns length of string without null terminator character, but strcpy requires that additional byte, so your allocating should look like that:
name = (char*)malloc(strlen(obj.name)+1);
2) When you copy employee, you copy pointer, so you have memory leak and employee pointer as a dangling one.
Also malloc cannot work with constructors, therefore after
employee = (struct Employee*)malloc(sizeof(obj.employee));
employee has a garbage inside.
Related
I am considering port of a complex code from boost::python to pybind11, but I am puzzled by the absence of something like boost::python::extract<...>().check(). I read pybind11::cast<T> can be used to extract c++ object from a py::object, but the only way to check if the cast is possible is by calling it and catching the exception when the cast fails. Is there something I am overlooking?
isinstance will do the job (doc) :
namespace py = pybind11;
py::object obj = ...
if (py::isinstance<py::array_t<double>>(obj))
{
....
}
else if (py::isinstance<py::str>(obj))
{
std::string val = obj.cast<std::string>();
std::cout << val << std::endl;
}
else if (py::isinstance<py::list>(obj))
{
...
}
Having a class with a private member
std::unordered_map<std::string, size_t> myMap;
and the corresponding getter
std::unordered_map<std::string, size_t> getMyMap() const {return myMap;}
I observe strange behaviour by applying std::unordered_map::find() two times, each time saving the returned iterator, e.g.
auto pos1 = test.getMyMap().find("a");
auto pos2 = test.getMyMap().find("a");
Altough I look for the same key "a" the iterator points to different elements. The following sample code illustrates the problem:
#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>
class MyMap{
public:
MyMap(){
myMap= {
{"a", 1},
{"b", 2}
};
}
std::unordered_map<std::string, size_t> getMyMap() const {return myMap;}
private:
std::unordered_map<std::string, size_t> myMap;
};
int main(){
MyMap test;
auto pos1 = test.getMyMap().find("a");
auto pos2 = test.getMyMap().find("a");
std::cout << pos1->first << "\t" << pos1->second << std::endl;
std::cout << pos2->first << "\t" << pos2->second << std::endl;
}
Compiling with g++ -std=c++11 and running gives
b 2
a 1
where the first line is unexpected. It should be "a 1".
Changing the code to
auto pos3 = test.getMyMap().find("a");
std::cout << pos3->first << "\t" << pos3->second << std::endl;
auto pos4 = test.getMyMap().find("a");
std::cout << pos4->first << "\t" << pos4->second << std::endl;
results in the correct output
a 1
a 1
Furthermore just creating an unordered_map in the main file and applying find() works. It seems the problem is connected to the getter-method, maybe to return-value-optimisation. Do you have any explanations for this phenomena?
It's because you have undefined behavior in your code. The getMyMap returns a copy of the map, a copy that is destructed once the expression test.getMyMap().find("a") is done.
This means you have two iterators that are pointing to no longer existing maps.
The solution is very simple: Make getMyMap return a constant reference instead:
std::unordered_map<std::string, size_t> const& getMyMap() const;
That it seems to work in the latter case, is because that's a pitfall of undefined behavior, it might sometime seem like it works, when in reality it doesn't.
test.getMyMap().find("a"); does find on a copy of original myMap which is destructed after the expression is complete, making the iterators pos1 and pos2 to non-existing map, invoking an undefined behaviour
Instead you can play around like following :
auto mymap = test.getMyMap() ; // Store a copy
auto pos1 = mymap.find("a"); // Then do stuff on copy
auto pos2 = mymap.find("a");
I'm trying to learn flex and lemon, in order to parse a (moderately) complex file format. So far, I have my grammar and lex file and I believe it is correctly parsing an example file. Right now, I want to pass the token text scanned with flex to lemon.
The flex YYSTYPE is defined as
#define YYSTYPE char*
The lemon token type is
%token_type {char *}
However, if I have a set of rules in lemon:
start ::= MATDEF IDENTIFIER(matName) LEFT_CURLY_BRACE(left) materialDefinitionBody(mBody) RIGHT_CURLY_BRACE(right) .
{
std::string r = std::string(matName) + std::string(left) + mBody + std::string(right);
std::cout << "result " << r << std::endl;
}
materialDefinitionBody(r) ::= techniqueList .
{
r = "a";
}
the output will be
result a
when it should be something like
mat1 { a }
My main parsing loop is:
void parse(const string& commandLine) {
// Set up the scanner
yyscan_t scanner;
yylex_init(&scanner);
YY_BUFFER_STATE bufferState = yy_scan_string(commandLine.c_str(), scanner);
// Set up the parser
void* shellParser = ParseAlloc(malloc);
yylval = new char[512];
int lexCode;
do {
yylval[0] = 0;
lexCode = yylex(scanner);
cout << lexCode << " : " << yylval << std::endl;
Parse(shellParser, lexCode, yylval);
}
while (lexCode > 0);
if (-1 == lexCode) {
cerr << "The scanner encountered an error.\n";
}
// Cleanup the scanner and parser
yy_delete_buffer(bufferState, scanner);
yylex_destroy(scanner);
ParseFree(shellParser, free);
}
The cout line is printing the correct lexCode/yylval combination.
What is the best way? I can't find anything that works.
You need to have
yylval = new char[512];
inside the do-while loop.
I'm running cygwin and use pselect to monitor a socket and filedescriptors for child processes.
According to some example that I found here http://www.linuxprogrammingblog.com/code-examples/using-pselect-to-avoid-a-signal-race and the man pages pselect should return the number of filedescriptors which are set in the mask fields (http://linux.die.net/man/2/pselect).
Now when I connect to my server pselect returns, which is fine. But when I test for the filedescriptors using FD_ISSET they always return true:
FD_ZERO(&readers);
FD_ZERO(&writers);
FD_ZERO(&exceptions);
FD_SET(fileno(stdin), &readers);
FD_SET(socket, &readers);
pret = pselect(FD_SETSIZE, &readers, &writers, &exceptions, NULL, &mSignalMask);
, &readers, &writers, &exceptions, NULL, &mSignalMask);
if(pret <= 0)
{
// ignore for now
continue;
}
if(FD_ISSET(fileno(stdin), &readers))
{
string s;
cin >> s;
cout << "stdin: " << s << endl; // blocks because the code always gets here even when
// pselect returns because of a childsignal without any data.
continue;
}
if(FD_ISSET(socket, &readers))
{
accept(); // blocks because the code always gets here even when
// pselect returns because of a childsignal without any data.
cout << "task created connection from " <<task->getClientHost() << endl;
continue;
}
Found the problem myself. FD_ISSET can ONLY be used if the result from pselect is > 0, otherweise the returnvalue from FD_ISSET is as before the call. So best treat it as undefined when pselect returns <= 0;
I'm sorry if this is vague I'm still pretty new to programming(also new to forums >_>)
Ok, my code is supposed to read in a number from a file, then use that number to read in that amount of words as dictionary words. I then store those words into an array and keep them for later usage. After the dictionary words in the file comes some paragraph, i read that in and set it to c-string array.(iv got that all down so far) But for the last part of the program i need to go back though that paragraph c-string and count how many times each dictionary word appears. I'm currently trying paragraph.find (word[0]) but i get some error that i don't know how to fix.
error: |40|error: request for member 'find' in 'paragraph', which is of non-class type 'char [2000]'|
code:
#include <iostream>
#include <fstream>
#include <cstring>
#include <windows.h>
using namespace std;
int main()
{
ifstream inStream; //declare ifstream
inStream.open("infile2.txt"); //open my file
int number; // number at the begining of the file that lets the program know
inStream >> number; // how many dictionary words are to be expected.
cout << number << " dictionary word(s)" << endl << endl;
char dict[30];
char text[2000];
char paragraph[2000]; // declareing some stuff
int count;
int position;
string word[5];
for (int i=0; i<number; i++) // using c string to set the 'number' amount of words in the dict array
{
inStream.getline(dict,30,'|');
word[i] = dict;
}
for (int i=0; i<number; i++) // cout so i can see its all set up right.
{
cout << "word " << i+1 << " is: " << word[i] << endl;
}
cout << endl;
inStream.get(paragraph,2000,'|'); // setting the rest of the paragrapg of the txt document to a c string
cout << paragraph; // so it can be searched later using the 'dict' words
position = paragraph.find (word[0]); // trying to find the position of the first word stored in 'dict[0]' but i run into an error
return 0;
}
the infile2.txt looks like this:
3steak|eggs|and|
steak and eggs and eggs and steak, eggs and steak, steak and eggs...
delicious.
c-strings are not classes and do not have a find method (or any other methods for that matter) i.e paragraph.find. You could try using a string or if you need to use c-strings a find method that takes two c strings as parameters.
such as This one