AV while iterating through hash_map? - c++

_transaction is a private member variable of my class, declared as:
public:
typedef stdext::hash_map<wchar_t*, MyClass*, ltstr> transaction_hash_map;
private:
transaction_hash_map _transactions;
During cleanup I am trying to iterate through this list and free up any objects still unfreed. However I am getting an AV on the for line here:
for (transaction_hash_map::const_iterator it = _transactions.begin(); it != _transactions.end(); it++)
{
MyClass* item = (MyClass*)it->second;
if (item != NULL)
{
item->End();
delete item;
}
}
Re: What is ltstr?
private:
struct ltstr
{
enum
{
bucket_size = 8,
min_buckets = 16
};
bool operator()(wchar_t* s1, wchar_t* s2) const
{
return wcscmp( s1, s2 ) < 0;
}
size_t operator()(wchar_t *s1) const
{
size_t h = 0;
wchar_t *p = const_cast<wchar_t*>(s1);
wchar_t zero = L'\0';
while ( *p != zero ) h = 31 * h + (*p++);
return h;
}
};
The stack shows it inside the begin() method. Any ideas?

One possible thing I can think of is that your class has already been deleted elsewhere before you try to iterate through the hash_map, and thus begin() will be operating on garbage. Worth a check...
Also - how are your wchar_t*'s getting allocated/freed? The code you've shown doesn't appear to be dealing with those. I'm not sure how that would cause trouble in your loop, but it's worth thinking about.
One minor thing - you shouldn't need the (MyClass*) cast. The hash_map's values should be of that type anyway, so it's nicer to let the compiler enforce type checks than to possibly bypass them with an explicit cast. That shouldn't be making any difference here though.

As I understand you're checking your pointer against NULL for the "remaining" items that might have not been deleted yet. But for the items you delete before your cleanup stage, do you set the pointer to NULL?
Notice that when you delete an object the pointer is not automatically set to NULL. So if you're not doing that you're trying to delete the same object twice (because your if statement will always be true), what could cause an access violation.
The code below is an example that causes a double deletion. It can be fixed if you uncomment the line that sets the pointer to NULL.
#include <cstddef>
struct Item {};
int main()
{
Item * p = new Item();
delete p;
//If you don't make the pointer null...
//p = NULL;
if (p != NULL)
//You delete the object twice.
delete p;
}
EDIT: I see you're getting the error exactly on the for line. So I'm wondering...
Apparently you have a MyClass that contains a _transactions member, which is a hash table with MyClass pointers as the data type. If the clean up code is performed inside a member function of MyClass, is it possible that you're deleting (for some reason) the MyClass instance that owns the _transactions you're iterating?
In this case you could get an error at it++ statement inside the for since the this object no longer exists. (Naturally, the error could be somewhere else too, like on the delete itself.)

Make sure to call _transactions.clear() after the for loop.

Related

Why is this returning true?

I started C++ a few hours ago and have been trying to do a simple LinkedList implementation in it to get myself familiar with it, however, I'm stumped as to why this method hasNext() keeps returning true.
#include <iostream>
#include <string>
using namespace std;
struct LinkedNode {
public:
int data;
LinkedNode(int d = 0) {
data = d;
}
void setNext(LinkedNode * linked_node) {
next = linked_node;
}
LinkedNode * getNext() {
return next;
}
bool hasNext() {
return (next != nullptr);
}
private:
LinkedNode * next;
};
int main() {
LinkedNode * linked_list = new LinkedNode(2);
(*linked_list).setNext(new LinkedNode(10));
if (linked_list->getNext()->hasNext()) {
cout << "true";
}
else {
cout << "false";
}
}
This outputs "true", but when I try to access the data since it is supposedly "true" I get the Segmentation fault error, (going to guess it's being raised since I'm trying to get a value that doesn't exist), from linked_list->getNext()->getNext()->data; Can somebody explain why?
The constructor of LinkedNode does not initialise the next member.
That means it is uninitialised. It is not set to zero by default. In fact, accessing its value (before initialising it, or assigning a value to it) gives undefined behaviour.
Set next to be nullptr within the constructor.
You are not initializing next. By default allocating memory just changes a data structure storing information about what memory block is allocated. It does not change the content of this memory block. So you can consider the next pointer be of random data. And since random data is different than null pointer hasNext returns true but when you access the data it is very likely that the random data is interpreted as a pointer into some memory that either does not exist or your application does not has the right to access too. Therefore the result in segmentation / page fault.
To verify this truth just do not initialize data as well, create some nodes and read the data (or even the next pointer). This way you see the randomness which is basically just left overs of content the memory block once hold before it was freed.
PS: Memory blocks are freed and dynamically spliced and combined based on algorithms you can learn. Check out malloc and some other implementations and see the Wikipedia about memory allocation.
You must initialize the value of next to nullptr. By default, the value is undefined (garbage).
Check out member initializer lists:
LinkedNode(int d = 0)
: data( d )
, next( nullptr )
{
}
Or simply assign the values directly in the constructor body:
LinkedNode(int d = 0)
{
data = d;
next = nullptr;
}

why does "a->content" give me a address instead of a value?

now i have been making games for a few years using the gm:s engine(tho i assure you i aint some newbie who uses drag and drop, as is all to often the case), and i have decided to start to learn to use c++ on its own, you know expand my knowledge and all that good stuff =D
while doing this, i have been attempting to make a list class as a practice project, you know, have a set of nodes linked together, then loop threw those nodes to get a value at a index, well here is my code, and i ask as the code has a single major issue that i struggle to understand
template<class type>
class ListNode
{
public:
type content;
ListNode<type>* next;
ListNode<type>* prev;
ListNode(type content) : content(content), next(NULL), prev(NULL) {}
protected:
private:
};
template<class type>
class List
{
public:
List() : SIZE(0), start(NULL), last(NULL) {}
unsigned int Add(type value)
{
if (this->SIZE == 0)
{
ListNode<type> a(value);
this->start = &a;
this->last = &a;
}
else
{
ListNode<type> a(value);
this->last->next = &a;
a.prev = this->last;
this->last = &a;
}
this->SIZE++;
return (this->SIZE - 1);
}
type Find(unsigned int pos)
{
ListNode<type>* a = this->start;
for(unsigned int i = 0; i<this->SIZE; i++)
{
if (i < pos)
{
a = a->next;
continue;
}
else
{
return (*a).content;
}
continue;
}
}
protected:
private:
unsigned int SIZE;
ListNode<type>* start;
ListNode<type>* last;
};
regardless, to me at least, this code looks fine, and it works in that i am able to create a new list without crashing, as well as being able to add elements to this list with it returning the proper index of those elements from within the list, however, beyond that the problem arises when getting the value of a element from the list itself, as when i ran the following test code, it didn't give me what it was built to give me
List<int> a;
unsigned int b = a.Add(313);
unsigned int c = a.Add(433);
print<unsigned int>(b);
print<int>(a.Find(b));
print<unsigned int>(c);
print<int>(a.Find(c));
now this code i expected to give me
0
313
1
433
as that's what is been told to do, however, it only half does this, giving me
0
2686684
1
2686584
now, this i am at a lost, i assume that the values provided are some kind of pointer address, but i simply don't understand what those are meant to be for, or what is causing the value to become that, or why
hence i ask the internet, wtf is causing these values to be given, as i am quite confused at this point
my apologies if that was a tad long and rambling, i tend to write such things often =D
thanks =D
You have lots of undefined behaviors in your code, when you store pointers to local variables and later dereference those pointers. Local variables are destructed once the scope they were declared in ends.
Example:
if (this->SIZE == 0)
{
ListNode<type> a(value);
this->start = &a;
this->last = &a;
}
Once the closing brace is reached the scope of the if body ends, and the variable a is destructed. The pointer to this variable is now a so called stray pointer and using it in any way will lead to undefined behavior.
The solution is to allocate the objects dynamically using new:
auto* a = new ListNode<type>(value);
Or if you don't have a C++11 capable compiler
ListNode<type>* a = new ListNode<type>(value);
First suggestion: use valgrind or a similar memory checker to execute this program. You will probably find there are many memory errors caused by dereferencing stack pointers that are out of scope.
Second suggestion: learn about the difference between objects on the stack and objects on the heap. (Hint: you want to use heap objects here.)
Third suggestion: learn about the concept of "ownership" of pointers. Usually you want to be very clear which pointer variable should be used to delete an object. The best way to do this is to use the std::unique_ptr smart pointer. For example, you could decide that each ListNode is owned by its predecessor:
std::unique_ptr<ListNode<type>> next;
ListNode<type>* prev;
and that the List container owns the head node of the list
std::unique_ptr<ListNode<type>> start;
ListNode<type>* last;
This way the compiler will do a lot of your work for you at compile-time, and you wont have to depend so much on using valgrind at runtime.

Deleting array error

So I have the following class method (will probably add more if requested):
EDIT 1:
Here is where paObject gets initialized and how it remains until it reaches setCapacity(int c)
template <Object>
ArrayClass<Object>::ArrayClass()
{
_size = 0; //default in case allocation fails
paObject = new Object[ARRAY_CLASS_DEFAULT_SIZE];
if (paObject == NULL)
throw Exception();
_size = ARRAY_CLASS_DEFAULT_SIZE;
}
It may be important to note that my class Vector extends (or whatever it is in c++) ArrayClass: class MyVector: virtual public ArrayClass<Object>{} and then later on in
template <class Object>
MyVector<Object>::MyVector() : ArrayClass<Object>()
{
_currSize = 0;
_incFactor = 5;
}
it forces to call the ArrayClass constructor.
template <Object >
void MyVector<Object>::setCapacity(int c)
{
int len = _currSize;
if (len > c) len = c;
Object* paNew = new Object[c];
if (paNew == NULL) throw Exception();
for (int i = 0; i < len; i++)
paNew[i] = paObject[i];
if (paObject != NULL)
delete[] paObject;
paObject = paNew;
_size = c;
if (_currSize > len)
_currSize = len;
}
When the error happens, the value of c is 6 and the value of _currSize (a class private int variable) is 1. It is also remarkable to remark that paObject is a class pointer of type Object (which is a template... etc. etc.) initialized with an array of Objects of size 1 by the time the error happens (Object* paObject = new Object[1]).
Everything executes fine up until it reaches the line delete[] paObject; at which point it gives me a Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) error.
I seriously don't understand what is wrong.
Help would be appreciated.
This error occurs when you have a heap problem.
Something like:
int *a = new char[1];
a[500] = 0;
then later, on totally unrelated object you will get an error on delete or new.
You haven't shown us where paObject is declared ... or where it's (re)initialized ...
... but that's almost certainly the problem.
If you haven't initialized it to NULL, it might contain random garbage. In which case it won't evaluate to NULL, and Bad Things will happen.
Similarly, if don't explicitly reset it to NULL, then Bad Things will also happen.
Of course, we don't even know if paObject is an array (allocated with "new []") ... because you haven't shown us.
BOTTOM LINE:
1) Make sure paObject is initialized before you use it, and correctly initialized before you re-use it.
2) If you treat it as an array object, make sure it's initialized as an array object
3) You also need to be careful about the differences between "Object", "Object references" (&Object or Object *), arrays of Objects. In particular, you need to consider when you're passing a reference to an existing object, or when you're (perhaps unintentially) creating a new object.
These links should help:
http://cplus.about.com/od/learning1/ss/constructors.htm
http://www.tutorialspoint.com/cplusplus/cpp_copy_constructor.htm
==================================================================
ADDENDUM:
It sounds like the error Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) is occurring because you're overwriting your array.
Object* paObject = new Object[1] // This is really easy to overwrite!
I don't see where in the code you're writing to paObject (or writing to some alias of paObject), but I'm almost certain that's the problem.
IMHO...

Does the vector still exists?

I'm having a problem in my c++ game related with the vector.
I want to know if theres any code that tells me if a vector still exists.
Example (x = a structure that I created):
vector<x*> var;
var.push_back(new x);
var[5]->Pos_X = 10;
And now what i want:
delete var[5];
if(var[5] still exists){
var[5]->Pos_X = 20;
}
What could be the code for var[5] still exists?
Unless you've actually set the pointer to null after deleting it, there's no real way to determine whether that slot in the vector contains a pointer to a live object or not.
So you'd need to:
delete vec[5];
vec[5] = NULL;
Then you could test
if (vec[5] == NULL)
to determine if there was "really" something at that location or not.
There is no code for that, not without extra careful work in your deleting process. If you store smart pointers you can do it like this:
vector<unique_ptr<x>> var;
// assuming you actually do add 6 or more elements to the vector
...
var[5].reset();
if (var[5]) { ... }
You could use var.size() to see if the vector contains a pointer at var[5], but that won't tell you whether the pointer is valid.
You could create a small wrapper class:
template <class T>
class wrapper {
bool valid;
T *data_;
public:
wrapper(T *d): data_(d), valid(true) {}
del() { delete data; valid = false; }
bool isValid() { return valid; }
T *data() { return valid ? data : NULL; }
};
std::vector<wrapper<x> > var;
var[5].del();
if (var[5].valid())
var[5].data()->Pos_X = 20;
Personally, I'd prefer to just ensure that all the pointers are valid all the time though.
calling delete you are deallocating memory pointed by that x*, so you still have pointer to some memory address that do not contain anymore what you excpected.
If you want to remove elements from vector consider using "erase"; then, if you don't want to erase but simply "cancel" the Nth element, structure is yours.. put some bool flag inside your structure.

pointers and references question

#ifndef DELETE
#define DELETE(var) delete var, var = NULL
#endif
using namespace std;
class Teste {
private:
Teste *_Z;
public:
Teste(){
AnyNum = 5;
_Z = NULL;
}
~Teste(){
if (_Z != NULL)
DELETE(_Z);
}
Teste *Z(){
_Z = new Teste;
return _Z;
}
void Z(Teste *value){
value->AnyNum = 100;
*_Z = *value;
}
int AnyNum;
};
int main(int argc, char *argv[]){
Teste *b = new Teste, *a;
a = b->Z();
cout << "a->AnyNum: " << a->AnyNum << "\n";
b->Z(new Teste);
cout << "a->AnyNum: " << a->AnyNum << "\n";
//wdDELETE(a);
DELETE(b);
return 0;
}
I would like to know if there is a memory leak in this code
it works ok, the *a is set twice and the AnyNum prints different numbers on each cout <<
but I wonder what happened to the _Z after the setter(new Teste), I don't have much knowledge in pointers/references yet, but for the logic I guess it is being swapped for the new variable
if it is leaking, is there anyway to accomplish this without having to set a to _Z again?
because the address didn't change, just the direct memory allocated
I was going to use *& instead of just pointers, but would it make difference?
There is a memory leak on this line:
b->Z(new Teste);
because of the definition of the function:
void Z(Teste *value){
value->AnyNum = 100;
*_Z = *value;
}
It looks like Z without arguments was supposed to be a getter and with arguments a setter. I suspect you meant to do:
void Z(Teste *value){
value->AnyNum = 100;
_Z = value;
}
(note the third line) That is, assign the pointer "value" to the pointer "_Z" instead of copy what value pointed at over what Z pointed at. With that, the first memory leak would be resolved, but the code would still have one since _Z could have been holding a pointer. So you'd have to do:
void Z(Teste *value){
value->AnyNum = 100;
delete _Z; // you don't have to check for null
_Z = value;
}
As mentioned in another comment, the real solution is to use smart pointers. Here's a more modern approach to the same code:
using namespace std;
class Teste {
private:
boost::shared_ptr<Teste> Z_;
public:
Teste() : AnyNum(5), Z_(NULL)
{ }
boost::shared_ptr<Teste> Z()
{
Z_.reset(new Teste);
return Z_;
}
void Z(boost::shared_ptr<Teste> value)
{
value->AnyNum = 100;
Z_ = value;
}
int AnyNum;
};
int main(int argc, char *argv[]){
boost::shared_ptr<Teste> b = new Teste, a;
a = b->Z();
cout << "a->AnyNum: " << a->AnyNum << "\n";
b->Z(boost::shared_ptr<Teste>(new Teste));
cout << "a->AnyNum: " << a->AnyNum << "\n";
return 0;
}
Yes there is:
void Z(Teste *value)
{
value->AnyNum = 100;
*_Z = *value; // you need assignment operator
}
The compiler-generated assignment operator will not make a deep copy, instead it will make a shallow copy. What you have to do is to write a suitable assignment operator (and possibly a copy constructor) for Teste. Also, you don't have to check if a pointer is NULL before deleting it:
~Teste()
{
// no need for checking. Nothing will happen if you delete a NULL pointer
if (_Z != NULL)
DELETE(_Z);
}
You've got another problem: _Z is not an identifier you should be using. In general, it's best to avoid leading underscores, and in particular double underscores or underscores followed by a capital letter are reserved for the implementation.
What a mess!
The whole program is very hard to read because of the choice of identifier names to start with:
#ifndef DELETE
#define DELETE(var) delete var, var = NULL
#endif
I find that very ugly.
When using classes it seems very un-nessacery. You could use it where a variables is going out of scope but it is a waster of time in the destructor. I think it would be asier to wrap the code in some smart pointer:
class Teste
{
private:
Teste *_Z;
public:
Teste()
~Teste() // Delete the _Z pointer.
Teste *Z();
void Z(Teste *value);
};
Ok. You have a pointer member that you delete in the destructor.
This means you are taking ownership of the pointer. This means that the ule of four applies (similar to the rule of three but applicable to ownership rules). This means you basically need to write 4 methods or the compiler generated versions will mess up your code. The methods you should write are:
A Normal (or default constructor)
A Copy constructor
An Assignment operator
A destructor.
Your code only has two of these. You need to write the other two.
Or your object should not take ownership of the RAW pointer. ie. use a Smart Pointer.
Teste *_Z;
This is not allowed.
Identifiers beginning with an underscore and a capitol letter are reserved.
You run the risk of an OS macro messing up your code. Stop using an underscore as the first character of identifiers.
~Teste(){
if (_Z != NULL)
DELETE(_Z);
}
This is not needed. Asimple delete _Z would have been fine.
_Z is going out of scope because it is in the destructor so no need to set it to NULL.
The delete operator handles NULL pointers just fine.
~Test()
{ delete _Z;
}
Teste *Z(){
_Z = new Teste;
return _Z;
}
What happens if you call Z() multiple times (PS putting the * next to the Z rather than next to the Teste make it hard to read).
Each time you call Z() the member variable _Z is given a new value. But what happens to the old value? Basically you are leaking it. Also by returning a pointer to an object owned
inside Teste you are giving somebody else the opportunity to abuse the object (delete it etc). This is not good. There is no clear ownership indicated by this method.
Teste& Z()
{
delete _Z; // Destroy the old value
_Z = new Teste; // Allocate a new value.
return *_Z; // Return a reference. This indicates you are retaining ownership.
// Thus any user is not allowed to delete it.
// Also you should note in the docs that it is only valid
// until the next not const call on the object
}
void Z(Teste *value){
value->AnyNum = 100;
*_Z = *value;
}
You are copying the content of a newly constructed object (that contains a pointer) into another dynamically created object!
What happens if _Z had not been allocated first. The constructor sets it to NULL so there is no guarantee that it has a valid value.
Any object you allocate you should also delete. But here value is dynamically allocated passed into Z but never freed. The reason you get away with this is because the pointer is c
opied into _Z and _Z is deleted when its destructor is destroyed.
Teste *b = new Teste, *a;
That's really heard to read. Don;t be lazy write it out properly.
This is considered bad style and you would never get past any code review with that.
Teste* b = new Teste;
Teste* a; // Why not set it to NULL
a = b->Z();
Getting ab object for a. But who was destroying the object a or b?
b->Z(new Teste);
It just gets too convoluted after that.
(I tried to add this as a comment but that screws up the code..)
I'd aslo strongly suggest not to use
#ifndef DELETE
#define DELETE(var) delete var, var = NULL
#endif
but instead something like
struct Deleter
{
template< class tType >
void operator() ( tType*& p )
{
delete p;
p = 0;
}
};
usage:
Deleter()( somePointerToDeleteAndSetToZero );
(not really an answer, but a comment wouldn't do)
The way you defined your macro is prone to a subtle errors (and the fact that no one spotted it so far just proves it). Consider your code:
if (_Z != NULL) // yes, this check is not needed, but that's not the point I'm trying to make
DELETE(_Z);
What happens after the preprocessor pass:
if (_Z != 0)
delete _Z; _Z = 0;
If you still have trouble seeing it, let me indent it properly:
if (_Z != 0)
delete _Z;
_Z = 0;
It's not a big deal, given that particular if condition, but it will blow-up with anything else and you will spend ages trying to figure out why your pointers are suddenly NULL. That's why inline functions are preferred to macros - it's more difficult to mess them up.
Edit: ok, you used comma in your macro definition so you are safe... but I would still say it's safer to use [inline] function in this case. I'm not one of the do-not-use-macros-ever guys, but I wouldn't use them unless they are strictly necessary and they are not in this case
void Z(Teste *value){
value->AnyNum = 100;
*_Z = *value;
}
and
b->Z(new Teste);
creates a memory leak
the 'new Teste' never gets deleted, instead what you are doing is allocating a new object as parameter, then copying whatever is in there using *_Z = *value but the object is not deleted after the call.
if you were to write
Test* param - new Teste;
b->Z(param)
delete param;
it would be better
of course most would use boost::shared_ptr or something similar to avoid caring about delete and such