<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[ThreadSafe ...]]></title><description><![CDATA[<p>hallo,</p>
<p>also ich habe eine DLL geschrieben,<br />
in der ich eine Klasse CriticalSection habe.<br />
wenn man die DLL nutzt und eine eigene Klasse von dieser ableitet, so soll die abgeleitete Klasse Thread-Safe sein.</p>
<p>dazu der Code der CriticalSection-Klasse:</p>
<p>ct_critical.hpp</p>
<pre><code class="language-cpp">#ifndef __CT_CRITICAL_SECTION_HPP__
#define __CT_CRITICAL_SECTION_HPP__

#include &quot;ct_types.hpp&quot;

#ifdef CTLIB2008_EXPORTS
#define CS __declspec(dllexport)
#else
#define CS __declspec(dllimport)
#endif

namespace ctlib
{
	class CS CriticalSection
	{
	protected:
		ct_pointer pCriticalSection;
	public:
		CriticalSection(void);
		virtual ~CriticalSection(void);
		virtual void Lock(void);
		virtual void Unlock(void);
	};
	typedef class CriticalSection ThreadSafe;
};

#endif
</code></pre>
<p>critical.cpp</p>
<pre><code class="language-cpp">#include &lt;windows.h&gt;
#include &quot;ct_critical.hpp&quot;

ctlib::CriticalSection::CriticalSection(void) : pCriticalSection(reinterpret_cast&lt;ctlib::ct_pointer&gt;(new CRITICAL_SECTION))
{
	InitializeCriticalSection(reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection));
}

ctlib::CriticalSection::~CriticalSection(void)
{
	DeleteCriticalSection(reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection));
	delete (reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection));
}

void ctlib::CriticalSection::Lock(void)
{
	while (!TryEnterCriticalSection(reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection)));
}

void ctlib::CriticalSection::Unlock(void)
{
	LeaveCriticalSection(reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection));
}
</code></pre>
<p>dann habe ich ein Testprogramm geschrieben:</p>
<pre><code class="language-cpp">#pragma comment(lib, &quot;CTLib2008.lib&quot;)

#include &lt;windows.h&gt;
#include &lt;conio.h&gt;
#include &lt;cstdio&gt;
#include &lt;ctlib/ct_critical.hpp&gt;

class CPoint : ctlib::CriticalSection
{
protected:
	int x, y;
public:
	CPoint(void) : x(0), y(0) { ctlib::CriticalSection::CriticalSection(); }
	CPoint(int _x, int _y) : x(_x), y(_y) { ctlib::CriticalSection::CriticalSection(); }
	virtual ~CPoint(void) { ctlib::CriticalSection::~CriticalSection(); }
	void SetX(int _x) { Lock(); x = _x; Unlock(); }
	void SetY(int _y) { Lock(); y = _y; Unlock(); }
	void SetXY(int _x, int _y) { Lock(); x = _x; y = _y; Unlock(); }
	int GetX(void) { Lock(); int ret = x; Unlock(); return ret; }
	int GetY(void) { Lock(); int ret = y; Unlock(); return ret; }
	void GetXY(int* px, int* py) { Lock(); *px = x; *py = y; Unlock(); }
};

DWORD WINAPI TestThread(LPVOID pParam)
{
	CPoint* pPoint = reinterpret_cast&lt;CPoint*&gt;(pParam);
	for (int n = 0; n &lt; 1000; n++)
	{
		pPoint-&gt;SetXY(n, n);
	}
	return 0;
}

int main(int argc, char** argv)
{
	CPoint p;
	DWORD dwID;
	HANDLE hThread = CreateThread(NULL, 0, TestThread, reinterpret_cast&lt;LPVOID&gt;(&amp;p), CREATE_SUSPENDED, &amp;dwID);
	if (!hThread)
	{
		printf(&quot;Fehler: Konnte Thread nicht erstellen!\n&quot;);
		_getch();
		return -1;
	}
	SetThreadPriority(hThread, THREAD_PRIORITY_BELOW_NORMAL);
	ResumeThread(hThread);
	for (int n = 0; n &lt; 10; n++)
	{
		int x, y;
		p.GetXY(&amp;x, &amp;y);
		printf(&quot;n=%d\tx=%d\ty=%d\n&quot;, n, x, y);
	}
	WaitForSingleObject(hThread, INFINITE);
	_getch();
	return 0;
}
</code></pre>
<p>das kompiliert und linkt auch einwandfrei.<br />
aber am Ende der main sagt mein Debugger:</p>
<blockquote>
<p>First-chance exception at 0x7c91eb74 in ctlib_test.exe: 0xC0000008: An invalid handle was specified.</p>
</blockquote>
<p>und als Stelle des Fehlers wurde mir das angezeigt:</p>
<pre><code class="language-cpp">ctlib::CriticalSection::~CriticalSection(void)
{
	DeleteCriticalSection(reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection)); // &lt;-- hier liegt der Fehler
	delete (reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection));
}
</code></pre>
<p>leider habe ich keine Erklärung für den Fehler, da ich ja die Critical Section nicht zwischendurch mal eben delete...</p>
<p>wäre sehr dankbar, wenn mir jemand helfen könnte, diesen Fehler zu beseitigen</p>
<p>MfG DrakoXP</p>
<p>PS.: ctlib::ct_pointer ist ein einfaches typedef auf void*, also:</p>
<pre><code class="language-cpp">namespace ctlib
{
    typedef void* ct_pointer;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/203346/threadsafe</link><generator>RSS for Node</generator><lastBuildDate>Mon, 27 Apr 2026 06:23:13 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/203346.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 21 Jan 2008 19:33:00 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to ThreadSafe ... on Mon, 21 Jan 2008 19:35:54 GMT]]></title><description><![CDATA[<p>hallo,</p>
<p>also ich habe eine DLL geschrieben,<br />
in der ich eine Klasse CriticalSection habe.<br />
wenn man die DLL nutzt und eine eigene Klasse von dieser ableitet, so soll die abgeleitete Klasse Thread-Safe sein.</p>
<p>dazu der Code der CriticalSection-Klasse:</p>
<p>ct_critical.hpp</p>
<pre><code class="language-cpp">#ifndef __CT_CRITICAL_SECTION_HPP__
#define __CT_CRITICAL_SECTION_HPP__

#include &quot;ct_types.hpp&quot;

#ifdef CTLIB2008_EXPORTS
#define CS __declspec(dllexport)
#else
#define CS __declspec(dllimport)
#endif

namespace ctlib
{
	class CS CriticalSection
	{
	protected:
		ct_pointer pCriticalSection;
	public:
		CriticalSection(void);
		virtual ~CriticalSection(void);
		virtual void Lock(void);
		virtual void Unlock(void);
	};
	typedef class CriticalSection ThreadSafe;
};

#endif
</code></pre>
<p>critical.cpp</p>
<pre><code class="language-cpp">#include &lt;windows.h&gt;
#include &quot;ct_critical.hpp&quot;

ctlib::CriticalSection::CriticalSection(void) : pCriticalSection(reinterpret_cast&lt;ctlib::ct_pointer&gt;(new CRITICAL_SECTION))
{
	InitializeCriticalSection(reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection));
}

ctlib::CriticalSection::~CriticalSection(void)
{
	DeleteCriticalSection(reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection));
	delete (reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection));
}

void ctlib::CriticalSection::Lock(void)
{
	while (!TryEnterCriticalSection(reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection)));
}

void ctlib::CriticalSection::Unlock(void)
{
	LeaveCriticalSection(reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection));
}
</code></pre>
<p>dann habe ich ein Testprogramm geschrieben:</p>
<pre><code class="language-cpp">#pragma comment(lib, &quot;CTLib2008.lib&quot;)

#include &lt;windows.h&gt;
#include &lt;conio.h&gt;
#include &lt;cstdio&gt;
#include &lt;ctlib/ct_critical.hpp&gt;

class CPoint : ctlib::CriticalSection
{
protected:
	int x, y;
public:
	CPoint(void) : x(0), y(0) { ctlib::CriticalSection::CriticalSection(); }
	CPoint(int _x, int _y) : x(_x), y(_y) { ctlib::CriticalSection::CriticalSection(); }
	virtual ~CPoint(void) { ctlib::CriticalSection::~CriticalSection(); }
	void SetX(int _x) { Lock(); x = _x; Unlock(); }
	void SetY(int _y) { Lock(); y = _y; Unlock(); }
	void SetXY(int _x, int _y) { Lock(); x = _x; y = _y; Unlock(); }
	int GetX(void) { Lock(); int ret = x; Unlock(); return ret; }
	int GetY(void) { Lock(); int ret = y; Unlock(); return ret; }
	void GetXY(int* px, int* py) { Lock(); *px = x; *py = y; Unlock(); }
};

DWORD WINAPI TestThread(LPVOID pParam)
{
	CPoint* pPoint = reinterpret_cast&lt;CPoint*&gt;(pParam);
	for (int n = 0; n &lt; 1000; n++)
	{
		pPoint-&gt;SetXY(n, n);
	}
	return 0;
}

int main(int argc, char** argv)
{
	CPoint p;
	DWORD dwID;
	HANDLE hThread = CreateThread(NULL, 0, TestThread, reinterpret_cast&lt;LPVOID&gt;(&amp;p), CREATE_SUSPENDED, &amp;dwID);
	if (!hThread)
	{
		printf(&quot;Fehler: Konnte Thread nicht erstellen!\n&quot;);
		_getch();
		return -1;
	}
	SetThreadPriority(hThread, THREAD_PRIORITY_BELOW_NORMAL);
	ResumeThread(hThread);
	for (int n = 0; n &lt; 10; n++)
	{
		int x, y;
		p.GetXY(&amp;x, &amp;y);
		printf(&quot;n=%d\tx=%d\ty=%d\n&quot;, n, x, y);
	}
	WaitForSingleObject(hThread, INFINITE);
	_getch();
	return 0;
}
</code></pre>
<p>das kompiliert und linkt auch einwandfrei.<br />
aber am Ende der main sagt mein Debugger:</p>
<blockquote>
<p>First-chance exception at 0x7c91eb74 in ctlib_test.exe: 0xC0000008: An invalid handle was specified.</p>
</blockquote>
<p>und als Stelle des Fehlers wurde mir das angezeigt:</p>
<pre><code class="language-cpp">ctlib::CriticalSection::~CriticalSection(void)
{
	DeleteCriticalSection(reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection)); // &lt;-- hier liegt der Fehler
	delete (reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection));
}
</code></pre>
<p>leider habe ich keine Erklärung für den Fehler, da ich ja die Critical Section nicht zwischendurch mal eben delete...</p>
<p>wäre sehr dankbar, wenn mir jemand helfen könnte, diesen Fehler zu beseitigen</p>
<p>MfG DrakoXP</p>
<p>PS.: ctlib::ct_pointer ist ein einfaches typedef auf void*, also:</p>
<pre><code class="language-cpp">namespace ctlib
{
    typedef void* ct_pointer;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1440880</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1440880</guid><dc:creator><![CDATA[DrakoXP]]></dc:creator><pubDate>Mon, 21 Jan 2008 19:35:54 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Mon, 21 Jan 2008 20:41:49 GMT]]></title><description><![CDATA[<p>Warum nimmst Du nicht einfach statt</p>
<pre><code class="language-cpp">protected:
        ct_pointer pCriticalSection;
</code></pre>
<p>dieses?</p>
<pre><code class="language-cpp">protected:
        CRITICAL_SECTION criticalSection;
</code></pre>
<p>Damit sparst Du Dir die new/delete-Aufrufe:</p>
<pre><code class="language-cpp">ctlib::CriticalSection::CriticalSection(void)
{
    InitializeCriticalSection(&amp;criticalSection);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1440917</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1440917</guid><dc:creator><![CDATA[sri]]></dc:creator><pubDate>Mon, 21 Jan 2008 20:41:49 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Mon, 21 Jan 2008 20:54:58 GMT]]></title><description><![CDATA[<p>weil ich die Klasse abstrahieren wollte...<br />
soll heißen, man soll das ganze auch mit einem Compiler ohne WinAPI nutzen können,<br />
also zum Beispiel, jemand hat von VC2005 die Express und kein PSDK...<br />
dann soll es eben trotzdem gehen,<br />
und deswegen habe ich eben den void* an der Stelle benutzt</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1440924</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1440924</guid><dc:creator><![CDATA[DrakoXP]]></dc:creator><pubDate>Mon, 21 Jan 2008 20:54:58 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Mon, 21 Jan 2008 22:46:38 GMT]]></title><description><![CDATA[<p>Da hast du aber mächtig viele Fehler drinnen.<br />
Ich hab den Code mal korrigiert, und mit ein paar Kommentaren versehen:<br />
(Ich hab' mir auch die Freiheit genommen einige &quot;Stilfehler&quot; zu korrigieren <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /> )</p>
<p>Header:</p>
<pre><code class="language-cpp">#ifndef INCLUDED_CT_CRITICAL_SECTION_HPP // keine doppelten underscores, solche namen sind reserviert!
#define INCLUDED_CT_CRITICAL_SECTION_HPP

#include &quot;ct_types.hpp&quot; 

#ifdef CTLIB2008_EXPORTS 
#define CTLIB2008_EXPORT __declspec(dllexport) // CS ist etwas mager
#else 
#define CTLIB2008_EXPORT __declspec(dllimport) 
#endif 

namespace ctlib 
{ 
	class CTLIB2008_EXPORT CriticalSection 
	{ 
		//protected: // das sollte IMO private sein
	private:
		//ct_pointer pCriticalSection; //das geht viel eleganter:
		class Impl; // forward decl einer nested class
		Impl* m_impl; // member fangen mit &quot;m_&quot; an
		// NOTE: auto_ptr&lt;Impl&gt; hier wäre ein fehler, da &quot;Impl&quot; ein &quot;incomplete type&quot; ist!!!
	public: 
		CriticalSection(); // das void in den Klammern ist überflüssig
		virtual ~CriticalSection(); // virtual hier kann sinn machen
		virtual void Lock(); // virtual hier ist fragwürdig (wollen abgeleitete klassen das überschreiben?)
		virtual void Unlock(); // ==''==

		// ScopedLock Klasse, damit man nicht mit Lock()/Unlock() rumfummeln muss:
		class ScopedLock
		{
		public:
			explicit ScopedLock(CriticalSection&amp; cs) :
				m_cs(cs)
			{
				m_cs.Lock();
			}
			~ScopedLock()
			{
				m_cs.Unlock();
			}
		private:
			CriticalSection&amp; m_cs;
		};

		// kopieren und zuweisen verhindern
	private:
		CriticalSection(CriticalSection const&amp;);
		CriticalSection&amp; operator =(CriticalSection const&amp;);
	}; 
	//typedef class CriticalSection ThreadSafe; // WTF?
}; 

#endif // INCLUDED_CT_CRITICAL_SECTION_HPP
</code></pre>
<p>Cpp:</p>
<pre><code class="language-cpp">#include &lt;windows.h&gt; 
#include &lt;stdexcept&gt;
#include &quot;ct_critical.hpp&quot; 

namespace ctlib { // so tun wir uns leichter

// definition nested class &quot;CriticalSection::Impl&quot; kommt hier
class CriticalSection::Impl
{
	friend class ::ctlib::CriticalSection;
	Impl()
	{
		if (!::InitializeCriticalSectionAndSpinCount(&amp;m_cs, 1000)) // InitializeCriticalSectionAndSpinCount hat einen returnwert, und ist daher vorzuziehen
			throw std::runtime_error(&quot;InitializeCriticalSectionAndSpinCount failed.&quot;);
	}

	~Impl()
	{
		::DeleteCriticalSection(&amp;m_cs);
	}

	CRITICAL_SECTION m_cs;
};

CriticalSection::CriticalSection() : // das ctlib:: brauchen wir nun nichtmehr, und wieder: kein void in den Klammern
	m_impl(new CriticalSection::Impl())
{ 
    // ::InitializeCriticalSection(...) // brauchen wir jetzt nichtmehr, wird von Impl::Impl erledigt
} 

CriticalSection::~CriticalSection() // s.o.
{ 
    //::DeleteCriticalSection(static_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection)); 
    delete m_impl; // kein cast mehr notwändig
} 

void CriticalSection::Lock()  // s.o.
{ 
    // while (!TryEnterCriticalSection(reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection))); // ganz böse, da gibts ne funktion dafür:
    ::EnterCriticalSection(&amp;m_impl-&gt;m_cs);
} 

void CriticalSection::Unlock()  // s.o.
{ 
	// LeaveCriticalSection(reinterpret_cast&lt;LPCRITICAL_SECTION&gt;(pCriticalSection)); // geht jetzt auch ohne cast
	::LeaveCriticalSection(&amp;m_impl-&gt;m_cs);
} 

} // namespace ctlib
</code></pre>
<p>Testprogramm:</p>
<pre><code class="language-cpp">#pragma comment(lib, &quot;CTLib2008.lib&quot;) 

#include &lt;windows.h&gt; 
#include &lt;conio.h&gt; 
#include &lt;cstdio&gt; 
#include &lt;ctlib/ct_critical.hpp&gt; 

class CPoint // hier tun wir jetzt nichtmehr private ableiten, Grund siehe unten
{ 
//protected: // was hast du nur mit protected...?
private:
	ctlib::CriticalSection mutable m_mutex; // hier lebt jetzt unsere CriticalSection, und zwar mutable, so können wir Funktionen auch const machen
    int m_x; // member mit m_, eins pro Zeile
    int m_y; 

public: 
    CPoint() : m_x(0), m_y(0)
    {
		//ctlib::CriticalSection::CriticalSection(); // das ist FALSCH, basisklassen werden immer automatisch konstuiert
		// davon abgesehen tun wir jetzt nichtmehr ableiten, aber member werden ja auch netterweise automatisch konstruiert
		// davon abgesehen tut ctlib::CriticalSection::CriticalSection garnicht was du denkst, sondern erzeugt ein objekt vom Typ ctlib::CriticalSection welches sofort wieder zerstört wird!
	} 

    CPoint(int x, int y) : m_x(x), m_y(y)
    {
		//ctlib::CriticalSection::CriticalSection(); // s.o.
	} 

    virtual ~CPoint()
    {
		//ctlib::CriticalSection::~CriticalSection(); // das ist wieder FALSCH, basisklassen werden immer automatisch zerstört
		// davon abgesehen tun wir jetzt nichtmehr ableiten, aber member werden ja auch netterweise automatisch zerstört
	}

    void SetX(int x)
    {
		ctlib::CriticalSection::ScopedLock lock(m_mutex);
		m_x = x;
	} 
    void SetY(int y)
    {
		ctlib::CriticalSection::ScopedLock lock(m_mutex);
		m_y = y;
	} 
    void SetXY(int x, int y)
    {
		ctlib::CriticalSection::ScopedLock lock(m_mutex);
		m_x = x;
		m_y = y;
    } 

    int GetX() const
    {
		ctlib::CriticalSection::ScopedLock lock(m_mutex); // ScopedLock will ne nicht-const Referenz auf die Mutex, das geht
		// jetzt hier trotzdem die Funktion &quot;const&quot; ist, da ja &quot;mutable&quot; verwendet wird
		return m_x; // das ist so OK, &quot;lock&quot; muss zerstört werden NACHDEM der Wert von x kopiert wurde
	} 

    int GetY() const
    {
		ctlib::CriticalSection::ScopedLock lock(m_mutex);
		return m_y;
	} 

    void GetXY(int* px, int* py) const
    {
		ctlib::CriticalSection::ScopedLock lock(m_mutex);
		*px = m_x;
		*py = m_y;
	} 
}; 

DWORD WINAPI TestThread(LPVOID pParam) 
{ 
    CPoint* pPoint = static_cast&lt;CPoint*&gt;(pParam);  // static_cast reicht aus
    for (int n = 0; n &lt; 1000; n++) 
    { 
        pPoint-&gt;SetXY(n, n); 
    } 
    return 0; 
} 

int main(int argc, char** argv) 
{ 
    CPoint p; 
    DWORD dwID; 
    HANDLE hThread = CreateThread(NULL, 0, TestThread, &amp;p, 0, &amp;dwID);  // reinterpret_cast unnötig, CREATE_SUSPENDED unnötig
    if (!hThread) 
    { 
        printf(&quot;Fehler: Konnte Thread nicht erstellen!\n&quot;); 
        _getch(); 
        return -1; 
    } 
    SetThreadPriority(hThread, THREAD_PRIORITY_BELOW_NORMAL); 
    //ResumeThread(hThread); // CREATE_SUSPENDED verwenden wir ja jetzt nichtmehr, sonst wäre das natürlich OK so
    for (int n = 0; n &lt; 10; n++) 
    { 
        int x, y; 
        p.GetXY(&amp;x, &amp;y);
        printf(&quot;n=%d\tx=%d\ty=%d\n&quot;, n, x, y); 
    } 
    WaitForSingleObject(hThread, INFINITE); 
    _getch(); 
    return 0; 
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1440975</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1440975</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 21 Jan 2008 22:46:38 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Mon, 21 Jan 2008 22:49:43 GMT]]></title><description><![CDATA[<p>Ahso, das ist natürlich ein Grund.</p>
<p>Mein Gefühl sagt mir, dass es etwas mit dem am Anfang von main deklarierten CPoint zu tun hat. Was passiert, wenn Du die Deklaration in die for-Schleife steckst?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1440976</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1440976</guid><dc:creator><![CDATA[sri]]></dc:creator><pubDate>Mon, 21 Jan 2008 22:49:43 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Mon, 21 Jan 2008 23:10:50 GMT]]></title><description><![CDATA[<p>Nein.<br />
Der Fehler der zu dem Absturz geführt hat war den Destruktor von CriticalSection manuell aus dem Destruktor von CPoint aufzurufen.<br />
Das führt dazu dass 2x DeleteCriticalSection aufgerufen wird, was natürlich Blödsinn ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1440987</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1440987</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 21 Jan 2008 23:10:50 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Tue, 22 Jan 2008 08:31:21 GMT]]></title><description><![CDATA[<p>ich dachte, das müsste so sein, da ich den Konstruktor ja auch im Konstruktor von CPoint manuell aufrufen muss.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441076</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441076</guid><dc:creator><![CDATA[DrakoXP]]></dc:creator><pubDate>Tue, 22 Jan 2008 08:31:21 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Tue, 22 Jan 2008 08:56:03 GMT]]></title><description><![CDATA[<p>DrakoXP schrieb:</p>
<blockquote>
<p>ich dachte, das müsste so sein, da ich den Konstruktor ja auch im Konstruktor von CPoint manuell aufrufen muss.</p>
</blockquote>
<p>Nein, den mußtest du gar nicht manuell aufrufen - und so, wie du es gemacht hast, was es unsinnig (in den Ctor'en hattest du eine lokale CS angelegt, die sofort wieder zerstört wurde).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441086</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441086</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 22 Jan 2008 08:56:03 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Tue, 22 Jan 2008 11:22:23 GMT]]></title><description><![CDATA[<p>Die Fehler sind alle in dem von mir geposteten Code kommentiert.<br />
Lies es doch wenigstens mal...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441197</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441197</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 22 Jan 2008 11:22:23 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Tue, 22 Jan 2008 14:52:05 GMT]]></title><description><![CDATA[<p>naja, so wie ich das jetzt sehe, hätte es gereicht, einfach bei CPoint im CTor und im DTor den Aufruf<br />
der CTor und Dtor der Basis-Klasse wegzulassen.</p>
<p>warum also so viel Arbeit?</p>
<p>und die stilistischen Sachen sind ja für den Endnutzer in dem Sinne soweiso egal...</p>
<p>gut, was private und protected angeht, hast du Recht...<br />
es ist wohl eher weniger sinnvoll, wenn geerbte Klassen an den CS-Daten rumspielen können.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441343</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441343</guid><dc:creator><![CDATA[DrakoXP]]></dc:creator><pubDate>Tue, 22 Jan 2008 14:52:05 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Tue, 22 Jan 2008 16:00:16 GMT]]></title><description><![CDATA[<p>Die anderen Sachen sind zum Grossteil auch sinnvoll, der reinterpret_cast ist z.B. strenggenommen einfach falsch.<br />
(Ich weiss, ich weiss, es funktioniert, und auf bestimmten Plattformen ist das Verhalten sogar garantiert, aber eben nicht auf allen. Wenn du schon Zeiger rumcasten willst dann mach aus dem Member einen void-Zeiger, und caste mit static_cast anstelle von reinterpret_cast.)<br />
Die &quot;const&quot; Geschichten solltest du auch ASAP lernen, je später du das lernst desto mehr Code musst du umschreiben (&quot;const correctness&quot; nachziehen ist ein Haufen Arbeit!).<br />
TryEnterCriticalSection in einer Schleife ist IMO ganz ganz böse.</p>
<p>Und die anderen Sachen... wenn du nicht willst lass es bleiben. Sind eigentlich alles nur Dinge die dir später die Arbeit erleichtern, aber wenn du nicht willst... zwingen werde ich dich nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441385</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441385</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 22 Jan 2008 16:00:16 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Tue, 22 Jan 2008 16:15:30 GMT]]></title><description><![CDATA[<p>ok, dann drei Fragen:</p>
<p>(1) wie funktioniert const correctness?</p>
<p>(2) was ist an dem TryEnterCriticalSection in der Schleife so verkehrt?<br />
also was könnte da schief gehen?</p>
<p>(3) solange man auf 32Bit-System arbeitet macht reinterpret_cast doch nichts anderes,<br />
als den kompletten Wert bit für bit zu kopieren, ohne den Typ zu beachten.<br />
also wo liegt das Problem?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441403</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441403</guid><dc:creator><![CDATA[DrakoXP]]></dc:creator><pubDate>Tue, 22 Jan 2008 16:15:30 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Tue, 22 Jan 2008 21:23:44 GMT]]></title><description><![CDATA[<p>ad 1) guck in der C++ FAQ lite nach: <a href="http://www.parashift.com/c++-faq-lite/const-correctness.html" rel="nofollow">http://www.parashift.com/c++-faq-lite/const-correctness.html</a></p>
<p>ad 2) es macht dir den Speicherbus/Hypertransport total zu, und verbrät mordsmässig unnötig Rechenzeit. Ganz besonders sobald mal 2 oder mehr Threads gleichzeitig in der &quot;try until available&quot; Schleife hängen. EnterCriticalSection legt den Thread nach einer Weile schlafen, also z.B. wenn nach 1000 mal Probieren immer noch nix gegangen ist (das &quot;1000&quot; hier ist übrigens die Zahl die du bei InitializeCriticalSectionAndSpinCount mitgibst). Der schlafende Thread wird dann aufgeweckt sobald die CRITICAL_SECTION wieder &quot;frei&quot; wird. Ist also deutlichst besser.</p>
<p>ad 3) Was reinterpret_cast macht ist in vielen Fällen &quot;implementation defined&quot;. Aber ganz egal ob es mit reinterpret_cast effektiv geht oder nicht, wieso willst du ein Konstrukt wir reinterpret_cast verwenden wenn der Standard uns void-Zeiger und static_cast für sowas zur Verfügung stellt?</p>
<p>----</p>
<p>Du scheinst nach dem Motto zu arbeiten &quot;wieso richtig wenns falsch auch geht&quot; (bzw. &quot;wieso richtig wenns irgendwie auch geht&quot;). Ich arbeite halt nach dem Motto &quot;wieso falsch wenns richtig auch geht&quot;.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441627</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441627</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 22 Jan 2008 21:23:44 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Tue, 22 Jan 2008 22:15:19 GMT]]></title><description><![CDATA[<p>naja, dann fragt man sich aber, warum reinterpret_cast auch zum Standard gehört...<br />
also muss es doch da auch irgendwelche Festlegungen geben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441653</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441653</guid><dc:creator><![CDATA[DrakoXP]]></dc:creator><pubDate>Tue, 22 Jan 2008 22:15:19 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Tue, 22 Jan 2008 23:56:29 GMT]]></title><description><![CDATA[<p>DrakoXP schrieb:</p>
<blockquote>
<p>naja, dann fragt man sich aber, warum reinterpret_cast auch zum Standard gehört...<br />
also muss es doch da auch irgendwelche Festlegungen geben.</p>
</blockquote>
<p>Dann lies halt den Standard.</p>
<p>Ich verwende reinterpret_cast eben wirklich nur wenn es sein muss, bzw. wenn ich genau weiss was ich tue, und es anders (Standardkonform) zu hässlich würde.<br />
Mir ist auch klar dass die Bereitschaft eines C++ Programmierers Dinge wie reinterpret_cast freizügig einzusetzen indirekt proportional zum Ausmass seiner C++ Kenntnisse ist, aber deswegen muss ich es noch lange nicht gut finden wenn die Kids wie wild rumcasten :^)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441685</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441685</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 22 Jan 2008 23:56:29 GMT</pubDate></item><item><title><![CDATA[Reply to ThreadSafe ... on Wed, 23 Jan 2008 10:03:36 GMT]]></title><description><![CDATA[<p>Da hat hustbaer meine volle Zustimmung!<br />
Siehe auch <a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-198873-and-start-is-0-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-.html" rel="nofollow">http://www.c-plusplus.net/forum/viewtopic-var-t-is-198873-and-start-is-0-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-.html</a></p>
<p>Martin</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1441841</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1441841</guid><dc:creator><![CDATA[Mmacher]]></dc:creator><pubDate>Wed, 23 Jan 2008 10:03:36 GMT</pubDate></item></channel></rss>