By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,652 Members | 1,682 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,652 IT Pros & Developers. It's quick & easy.

"Debug Assertion Failed" On Smart Pointer

P: n/a
I read a section of my text on smart "counting" pointers and found it
confusing so I decided to get hands-on.

however I'm getting "Debug Assertion Failed... Expression:
_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)" whenever I run my code below.
program works fine after I bypass the msg.

any ideas? thx a lot.
#include "stdafx.h"

#using <mscorlib.dll>

using namespace std;

template <class T> class CountedPtr
{
public:

T* ptr;
long* count;

void dispose()
{
if((--(*count)) == 0)
{
delete count;
delete ptr;
}
}

explicit CountedPtr(T* p = 0) : ptr(p), count(new long(1))
{
}

CountedPtr(const CountedPtr <T>& p) throw() : ptr(p.ptr),
count(p.count)
{
++(*count);
}

~CountedPtr() throw()
{
dispose();
}

CountedPtr <T>& operator= (const CountedPtr <T>& p) throw()
{
if(this != &p)
{
dispose();
ptr = p.tr;
count = p.count;
++(*count);
}
return *this;
}

T& operator*() const throw()
{

return *ptr;
}

T* operator->() const throw()
{
return ptr;
}
};

int _tmain()
{
int i = 10;
int* sampleIntPtr = &i;

cout << *sampleIntPtr << "\n\n";

CountedPtr <int> countedIntPtr(sampleIntPtr);
CountedPtr <int> countedIntPtr2 = countedIntPtr;

cout << *countedIntPtr << "\n\n";
cout << *countedIntPtr2 << "\n\n";
cout << *(countedIntPtr.count) << "\n\n";
cout << *(countedIntPtr2.count) << "\n\n";

CountedPtr <int> countedIntPtr3 = countedIntPtr2;
CountedPtr <int> countedIntPtr4 = countedIntPtr2;

cout << *(countedIntPtr.count) << "\n\n";

return 0;
}

Oct 6 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
* A_*********@hotmail.com:
I read a section of my text on smart "counting" pointers and found it
confusing so I decided to get hands-on.
You read what you had written yourself, and got confused?

however I'm getting "Debug Assertion Failed... Expression:
_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)" whenever I run my code below.
program works fine after I bypass the msg.
Most probably not (works fine, that is).

any ideas? thx a lot.
#include "stdafx.h"
This is not a standard header.

#using <mscorlib.dll>
This is a non-standard directive, a language extension for some compiler.

using namespace std;

template <class T> class CountedPtr
{
public:

T* ptr;
long* count;
Should not be public.

void dispose()
{
if((--(*count)) == 0)
{
delete count;
delete ptr;
}
}


Already you're in deep waters. 'dispose' allows the client code to invalidate
the 'count' and 'ptr' members, and then call 'dispose' again, bang crash.

Also, this kind of logic belongs in the destructor.

Leveraging constructors and destructors is what smart-pointers are all about,
implementation-wise, so that's what you should do if you're implementing a
smart-pointer.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Oct 6 '05 #2

P: n/a
Alf P. Steinbach wrote:
* A_*********@hotmail.com:
I read a section of my text on smart "counting" pointers and found it
confusing so I decided to get hands-on.


You read what you had written yourself, and got confused?

textbook.

#include "stdafx.h"


This is not a standard header.

#using <mscorlib.dll>


This is a non-standard directive, a language extension for some compiler.

using Visual Studio 2003 which automatically generated those.

using namespace std;

template <class T> class CountedPtr
{
public:

T* ptr;
long* count;


Should not be public.

okay!

void dispose()
{
if((--(*count)) == 0)
{
delete count;
delete ptr;
}
}


Already you're in deep waters. 'dispose' allows the client code to invalidate
the 'count' and 'ptr' members, and then call 'dispose' again, bang crash.

Also, this kind of logic belongs in the destructor.

Leveraging constructors and destructors is what smart-pointers are all about,
implementation-wise, so that's what you should do if you're implementing a
smart-pointer.

thx for shedding light on that.

I was just wondering if you could discuss the single argument
constructor:
explicit CountedPtr(T* p = 0) : ptr(p), count(new long(1))
{
}
namely, why is 'explicit' being used? why is the value zero being
assigned to the pointer argument? and what's with the ':'? it doesn't
look like inheritance has any relevance here.

thx again.

Oct 6 '05 #3

P: n/a
* A_*********@hotmail.com:

I was just wondering if you could discuss the single argument
constructor:

explicit CountedPtr(T* p = 0) : ptr(p), count(new long(1))
{
}
namely, why is 'explicit' being used?
It prevents automatic (implicit) conversion of a T* to a CountedPtr where a
CountedPtr is expected, but why the designed wanted that only s/he knows.

why is the value zero being assigned to the pointer argument?
That's a default value.

and what's with the ':'? it doesn't
look like inheritance has any relevance here.


That's a constructor initializer list; I think it's discussed in the FAQ.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Oct 6 '05 #4

P: n/a
A_*********@hotmail.com wrote:
{
int i = 10;
int* sampleIntPtr = &i;

cout << *sampleIntPtr << "\n\n";

CountedPtr*<int>*countedIntPtr(sampleIntPtr);


Here you're binding a smart pointer to the address of a local automatic
variable. This makes no sense. Smart pointers serve the purpose of
automatically releasing dynamically allocated objects when they're no
longer needed. Your code, then, ends up with invoking 'delete' on a pointer
which hasn't been returned by 'new', which, of course, yields undefined
behaviour.

Max
Oct 6 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.