|
thank you , this article was useful for me.
i call PostMessage api function end of myThreadFun.
Zo.Naderi-Iran
|
|
|
|
|
you are welcome
btw, if you didnt check the page; http://win32assembly.online.fr
Iczelion page is great...
|
|
|
|
|
In a vector are stored class pointers;
<br />
class sample1 : public mybase<br />
{<br />
}<br />
<br />
vector<sample1*> vec;<br />
I would like to cast it;
<br />
vector<mybase*> *result = (vector<mybase*>*)&vec;<br />
I got a response previously that it is not possible, but i dont understand why.
Actually i am not sure this is a problem for my core dump.
I have been thinking about; if i have pointer stored inside vector, at the end it
is stored as address to something and the address is the same size in any case. So
if i cast it, there should be no changes, but i still got a core dump (it works for
instance in 20 cases, but then one crashes).
Can someone enlighten me what is wrong (or it is correct and i have problem somewhere else?)?
Thank you...
|
|
|
|
|
It's possible but perverse. Technically there is a chance it will be dangerous; for example an explicit specialisation could make the construct unsafe. In practice it could be made to work however.
There is no need to even think about such perversions in your case; a pointer to a derived class can be implicitly cast to a base type. Just use your sample1* s as if they were mybase* s and don't have any casts at all.
Steve
|
|
|
|
|
Why i need it;
http://www.codeproject.com/script/comments/forums.asp?msg=1841069&forumid=1647#xx1841069xx
What i am doing;
i am storing pointer to a vector inside some dispatch table that is stored in a base class for any class i am using.
vector holds further pointers to classes
pointer to vector is stored as void* (to avoid adding #includes to library that i wrote as generic), so i need to
cast it to vector but as i dont have #include to stored class definition the only thing i can cast it to is baseclass*.
when i want to gather its data, i call function in that base class that takes vector pointer
and casts it to vector<baseclass*>*, then i iterate through those class pointers and
gather their data,...
in that process i dont manipulate its content i am just reading what is stored inside and call
stored class* functions.
Unfortunally somewhere in (large and hard to handle) class structure some vector is annoying me
as:
<br />
+ _STL::_Vector_base<serClass *,_STL::allocator<serClass *> > {_M_start=0xcccccccc _M_finish=0x00579264 const serIO::`vftable' _M_end_of_storage={_M_data=0x010cf778 } } _STL::_Vector_base<serClass *,_STL::allocator<serClass *> ><br />
_M_start=0xcccccccc and it crashes.
before that the same freaking code is called around 20 times and it works without any problem.
Whole thing is going on in two processes, sending large class structures via sockets from one to another and vice versa, and is hell to trace so i am trying to theoretically find a problem
-- modified at 3:21 Monday 15th January, 2007
|
|
|
|
|
yeti11 wrote: I have been thinking about; if i have pointer stored inside vector, at the end it
is stored as address to something and the address is the same size in any case. So
if i cast it, there should be no changes, but i still got a core dump (it works for
instance in 20 cases, but then one crashes).
I am not sure what you are trying to accomplish, but if a vector is auto-expanding, any pointers would no longer relate to the current location in memory. This is one reason why pointers are discouraged with STL, and even iterators have to be used cautiously. Both an advantage and disadvantage, STL automatically allocates, and reallocates memory to extend itself.
The iterators/pointers will be valid only as long as the size of the vector remains the same, when you add to the vector, depending on its current size, it could expand to fit the new information, and change memory location.
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/d6fa8209e754aab9/11c794375a7bd8a3%2311c794375a7bd8a3[^]
_________________________
Asu no koto o ieba, tenjo de nezumi ga warau.
Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
|
|
|
|
|
I will try to explain it in an answer to Stephen Hewitt, please check it there...
|
|
|
|
|
You can't convert a vector<sample1*>* to a vector<mybase*>* because those two types are not in a base-derived relationship. It's that simple. It doesn't matter what type is contained in the vector.
As has already been stated, the right way is to remove the cast and do the conversion to mybase* on the individual elements as you access them.
|
|
|
|
|
The simple things are where the hell hides
Can you please tell me why? Pointer is a pointer however you turn it... sure if it is object i
understand the reason, but the question is what is the problem if i use it as pointer? Or rather
the question is understanding...
As far as i understand, the only difference between vector<bla*> and vector<some*> is
in casting on [] or at(). And if "bla" is derived from "some" the cast is not a problem.
btw, concerning casting; i simply cant do it other way, at the point where i am needing the cast
i am asking for i have no idea what type is stored inside, the only thing i do know is what is
base class. i dont want to loose general usage of library and coupling it with like 15 classes
that have nothing to do with it and... well it would be a mess.
(i am sorry, i dont want to be annoying but i am not bible kind of guy (god said; thou shall not
cast vectors) i want to understand what i am doing wrong and why.)
|
|
|
|
|
yeti11 wrote: i dont want to loose general usage of library and coupling it with like 15 classes
that have nothing to do with it and... well it would be a mess.
Not necessarily. You can hide the 15 classes within design patterns based on construction and/or behavior as appropriate to the 15 classes. The example given in Wikipedia is a very common one for a bridge, every object class for computer drawing has a "draw" function, at the far end the draw() is generic, you don't care what is being drawn, the information held within allows you to draw almost any shape and add more shapes.
http://en.wikipedia.org/wiki/Bridge_pattern[^]
look at the C++ code for drawing Circles and Squares from the same "shape" class. Is this the type of generic bridge you are trying to accomplish?
yeti11 wrote: i want to understand what i am doing wrong and why
without actually seeing your code, I can't tell you where the error lies for sure. The design via pointers is dangerous because of the STL habit of automatically changing its memory structure. Also pointers are not always held constant between threads, depending on when the pointers are built, and assigned the memory may not be shared between threaded operation calls.
Which brings us back to generic classes to hide implementation. Bridges or Composites[^] and building with other abstraction classes such as Builder[^]
Take a look through the gang-of-four Design Patterns[^] and see if one of those is what you are trying to achieve.
_________________________
Asu no koto o ieba, tenjo de nezumi ga warau.
Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
|
|
|
|
|
In class constructors all the variables that i want to have (de)serializable are stored in
a form &m_variable (+type) and then stored in dispatch table as void* (!)
When i call serialization over whole class hirarchy, the only thing i have is void* (!) so
if i want to do anything, i NEED to cast it to something.
At the time of serialization, there is nothing that would shrink/grow array.
I have ways of solving it with redesign, thank you everyone for trying to help, but if i
would want that, i would already do it. Unfortunaly no one is talking about the question;
What is wrong with casting vector holding pointers?
I'll try to reexplain my point; if vector is holding pointers to whatever, it can be casted
as nothing is changed internally (look on template as on freaking macro). in any case holding
WHATEVER pointer, the internal storage per "record" is size of pointer (, address, 4 bytes on
32 bit machine, in memory it is the same).
Please can someone think about what i am saying?
(multithreading is far outside this topic, the problem is not thread related)
|
|
|
|
|
yeti11 wrote: What is wrong with casting vector holding pointers?
Nothing, "per se" the problem with pointers is it is simply easier to make "unsafe code" which means the chances of a small bug like this one, are increased significantly above other alternatives. The reason for the alternatives is that you can spend a week tracking down this one bug, or another one, simply because the pointers give you the freedom to shoot yourself in the foot. It isn't the pointers fault really, a pointer is simply power, of course there is the ultimate power phrase, which applies to other pointer problems, but not this one. This is why you hear so many people say "no pointers, don't do this" and it isn't because it "cannot be done" it is because "the chances increase for error." You spend more time debugging than you do writing the code, time/money lost, etc. That is the primary reason to avoid pointers.
You can eventually figure this out, and we can all toss you out a hundred "small" errors that could be causing the problem. You'd probably get twice the number of suggestions from running something like PC-Lint on the code. Eventually one will be right. You find it, fix it, and all is okay. But the reason why folks are discouraging the pointer use, is because of the great number of "little" things that can go wrong.
We don't know your code, you do. You can't post all of your code, from the idea of IP and also space, so all any of us can do is generalize, offer some suggestions. But the primary reason folks are telling you to avoid the pointers is because it just increases the chance for these bugs. Generally speaking there is absolutely nothing wrong with pointers, pointers are good, pointers are powerful, and good written code with pointers works very well. It's just harder to get there, or find problems like this.
I've written programs with pointers, I've multi-threaded pointers, I have done near every great thing in the book with pointers. I have also made every mistake in the book with pointers. I use alternatives as often as possible, even in multi-object node storage, such as graphical scene graphs, which are my business.
Obviously I am not helping, so I will wish you well. I hope you find it and soon. Good luck in this and everything else.
Jeff
_________________________
Asu no koto o ieba, tenjo de nezumi ga warau.
Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
|
|
|
|
|
yeti11 wrote: Can you please tell me why? Pointer is a pointer however you turn it... sure if it is object i
understand the reason, but the question is what is the problem if i use it as pointer? Or rather
the question is understanding...
Sure a pointer is a pointer but the object it points to is not altered by casting the pointer. Consider the following:
#include <iostream>
class CClass1
{
public:
CClass1() : m_Data(0) {}
int m_Data;
};
class CClass2
{
public:
CClass2() : m_pData("Hello") {}
const char* m_pData;
};
void main()
{
using namespace std;
CClass2 c2;
CClass1 *pOne = reinterpret_cast<CClass1*>(&c2);
cout << pOne->m_Data << endl;
}
This program will not behave as expected. The cast from CClass2* to CClass1* does not change the CClass2 into a CClass1 ; it just changes the type of the pointer. So the compiler thinks that pOne points to an object of type CClass1 but it actually points to a CClass2 instance.
Steve
|
|
|
|
|
It's not that simple. The following program while perverse compiles and runs just fine and works as expected:
#include <iostream>
#include <vector>
class CBase
{
public:
virtual void Print() { std::cout << "CBase" << std::endl; }
};
class CDerived : public CBase
{
public:
virtual void Print() { std::cout << "CDerived" << std::endl; }
};
int main(int argc, char* argv[])
{
typedef std::vector<CBase*> BVec_t;
typedef std::vector<CDerived*> DVec_t;
DVec_t dvec;
dvec.push_back(new CDerived);
BVec_t &bvec = *reinterpret_cast<BVec_t*>(&dvec);
CBase *pBase = bvec.front();
pBase->Print();
delete pBase;
return 0;
}
Like I said in my previous post; it's possible in some instances but perverse and not necessary. Also it only works because the memory layouts of both classes happen to be the same, an explicit specialisation could change this (like std::vector<bool> ).
Steve
|
|
|
|
|
Ok... Stephen Hewitt as from the start, you are moving to my direction, something like this is what i have.
I am talking explicitly about vector<something*> as i am handling all other types differently.
Well thank you, it didnt help me solve the problem but it did help me to abandon the idea that something is
wrong with cast (unless someone will say something that explains why i shouldnt do it).
(i dont know if those "rate" points are helpfull to you but anyway i will give you 5 for both posts)
|
|
|
|
|
yeti11 wrote: but it did help me to abandon the idea that something is
wrong with cast
Don't abandon this idea; the cast is perverse and is asking for trouble. The troubles you’ll encounter with this type of thing are amongst the hardest to track down. In short, you’re short-circuiting the compiler’s type checking so a whole class of problem that would normally result in compiler errors now result in runtime errors instead. It was not my intention to encourage bad design.
Steve
|
|
|
|
|
"It was not my intention to encourage bad design."
Well, we shall see, i'll gladly post the results here I know it is
hack but it saves so much complications, not to mention that it keeps
code nice and clean, alternative i was thinking about is to do my own
template that would internally store vector<mybase*> but on the
outside casts will be made on [] and at(). Instead of storing pointer
to this "wrapper" template i will store pointer to internal vector and
as internally the type is allways the same, but on the outside it is
still used as it was. In any case this is gonna be firmly tested, if
it fails i'll know.
imho, as far as i can logically think about the cast, there should be nothing
wrong with it. Actually i am casting from vector<dword>* to vector<dword>*
|
|
|
|
|
As I said, in your case it will work. Nevertheless, in general, it is an unforgivable design decision. I’ve also mentioned that template specialisation could also invalidate this construct although the chances of this occurring are fairly slim. If was an employer and one of my employees done this without a bloody good reason I’d fire him on the spot. Naturally their are exception to every rule but in general there is very little places you need to pull this kind of hackery.
Steve
|
|
|
|
|
Damn, do you never sleep?
Ok, ok, lets say you convinced me, i am gonna write freaking templates today (*grumble*),
although i am still pissed of that this should be declared as a hack.
I hate templates and i believe at the end there is allways a good reason not to use them
(speed, redundancy in binary, MESS) but unfortunally this time i was pushed into them as
too much code depending on them to change it. Oh well, its a living
|
|
|
|
|
I think templates kick ass. If you use them right runtime speed is one of the advantages of templates.
Steve
|
|
|
|
|
Yeah i forseened that Well have a nice day/night...
|
|
|
|
|
I have read your post and the answers to it, before posting mine:
1) Do not do that!
2) Do not even think about doing that!
3) If you have to, then redesign it so that it is not required.
Why don’t you just use a virtual base class and store a pointer to that in the vector?
class A
{
public:
A() {}
virtual ~A() { std::cout << "destroying class A" << std::endl; }
virtual print() const { std::cout << "class A" << std::endl; }
};
class B : public A
{
public:
B() {}
virtual ~B() { std::cout << "destroying class B" << std::endl; }
virtual print() const { std::cout << "class B" << std::endl; }
};
int main()
{
std::vector<A*> a_vec;
int i;
for( i=0; i<3; ++i )
a_vec.push_back(new B);
for( i=0; i<3; ++i )
a_vec[i]->print();
for( i=0; i<3; ++i )
delete a_vec[i];
return 0;
}
Then if you need to access a method that is in a derived class that is not defined in the base class, use dynamic_cast . You can check the pointer, returned by the cast, to insure that it is not null, which would indicate that the cast would be invalid.
I hope that helps.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
Thank you for the answer, but i would rather point to 1) and 2) WHY?
|
|
|
|
|
Better late than never!
1) It overly complicates a simple operation and any methods available in the base class are also available in the derived class, unless the base class was declared private; in which case I would hope the complier rejects it. The idea is to find the simplest overall solution to a problem, making it easier to understand and implement. Except in a very narrow niche, this type of conversion should be avoided as it can introduce unexpected side effects.
2) Well that was a bit of an over statement. I can see thinking about it, but my mind automatically rejects that line of thought as anything more than a means to better understand the language.
If you need to store pointers to the derived class in a vector, other than a vector of base class pointers, then use dynamic_cast to convert the individual pointers on a per pointer bases, as needed. I do feel though that if you need to do this, then there is a fundamental flaw in the design.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
Hello, everyone, I'm a beginner of windows programming. Now I've got a problem on thread.
I wrote the following codes:
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hT1;
hT1 = CreateThread(NULL, 0, Thread1, NULL, 0, NULL);
CloseHandle(hT1);
cout<<"main thread"<
|
|
|
|
|