C++ Zeiger-Problem

Hallo an Alle,
ich habe folgendes Problem:
Ich versuche in meinem Programm einen Thread zu erstellen und an diesen einen Int Parameter zu übergeben. Allerdings muss ich diesen als Zeiger übergeben, was theoretisch auch machbar wäre ich den Zeiger nach der Übergabe in einer Schleife nochmal vergrößern möchte und dann wieder einen neuen Thread erstellen.

Hier ist der Code:
Code:
#include <string.h>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>

DWORD WINAPI MainFuncThread(LPVOID lpParam) //Main Thread aufrufen(Wird per Thread aufgerufen!)
{
int DLLNumber = (int)lpParam; //lpParam in Int umwandeln.
_tprintf (TEXT("Shout here from Thread %i\n"),DLLNumber);
// ...
return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
int* DLLNumber = 0;
CreateThread(NULL,0,MainFuncThread,DLLNumber,NULL,NULL);

DLLNumber++; //Geht nicht wie kann ich das erreichen?

// ...
CreateThread(NULL,0,MainFuncThread,DLLNumber,NULL,NULL);

return 0;
}

Ich weiß es ist eine Anfänger-Frage aber ich hab echt ewig gegoogelt und nix gefunden, was mein Problem lösen könnte. Diese dummen Zeiger immer! X(

Vielen Dank für die Hilfe!
 
Ein Zeiger bestitzt in dem Sinne keinen Inhalt - nur einen "Verweis" auf einen Inhalt.
D.h: Du erstellst ersmal eine normale int Variable.
Dann lässt Du einen Zeiger vom Typ INT darauf zeigen. Nun kannst Du die eigentliche Variable manipulieren.
Bsp:
Code:
int a=0;
int* zeiger_auf_a=&a;
a++;
 
Vielen Dank für deine Antwort aber wenn ich das so mache, dann gibt er mir eine riesige Zahl bei MainThreadFunktion aus. Weiß nicht woran das liegt aber ich glaube der übergibt dann anstatt 0 die Adresse.
 
Vorneweg: Dein Problem hat nichts mit Threads zu tun, sondern mit dem grundlegend noch nicht vorhandenen Verständnis von Zeigern. Was nicht schlimm ist. Aber Du solltest schrittweise vorgehen.

Langfristige Aussicht:

Was Du willst, ist eine "Inter-Process-Communication" auf der Ebene von Threads.

Guter Startpunkt zum Einarbeiten:
http://en.wikipedia.org/wiki/Inter-process_communication

Kurze Orientierung:

Die Speicherbereiche von Threads sind standardmäßig nicht getrennt.
Bei "Prozessen" sieht das entgegengesetzt aus.

Weil Du nur Threads zusammenarbeiten lassen willst, brauchst Du normalerweise keine Kapriolen mit Übergabe von Parametern über irgendwelche weiten Wege zu veranstalten. Es reicht, Variable im globalen Namespace direkt zu benutzen.
WAS daran interessant wird, ist die Synchronisation des Zugriffs. Nimm Dir das aber wirklich erst vor, nachdem Du mit Zeigern hantieren kannst!

Die Variablenübergabe in den Thread-Start-Parametern ist nur eine bequemere Art bzw. eine Methode, den Code in sich "lokal" abgeschlossen (und damit anständig modular) zu halten.

----

Zu Deinem Entwicklungsstand:

Was bei Dir stört, ist nur die Kleinigkeit, daß der Inhalt von dem, wo "DLLNumber" drauf zeigt, weder initialisiert (das ist der Grund für die von Dir angesprochene "große Zahl") noch von Dir benutzt wird. Statt dessen biegst Du nutzlos am Zeiger herum.

Du solltest Dich dringend vor dem Beginn von Thread-Konstruktionen (das ist bereits komplexe Programmierung) mit dem grundlegenden Konzept von Zeigern vertraut machen (das ist ungefähr zwei, drei Ebenen unterhalb von sowas wie Threads)!

Wenn Du das, was CDW geschrieben hat, anwenden kannst, passiert erstmal nichts mehr mit irgendwelchen komischen Werten.

Code:
int eine_nummer = 0;

// vollkommen überflüssig, aber WENN es denn sein muß:
int* DLLNumber = &eine_nummer;
CreateThread(NULL,0,MainFuncThread,DLLNumber,NULL,NULL);

// Es geht auch ohne den Zeiger erst extra und vollkommen nutzlos anzulegen:
CreateThread(NULL,0,MainFuncThread,&eine_nummer,NULL,NULL);


// im Thread genauso wie hier im Hauptprogramm möglich, aber sinnlos hintenherum:
* DLLNumber++;
// (bitte den Dereferenzierer (das Sternchen vorn) beachten!)

// sinnvoller, solange Du eh nur von der einen Variablen ausgehst:
eine_nummer++;

Viel Erfolg beim weiteren Einarbeiten!
 
Hi erstmal vielen dank für die Hilfe. So hab ich das auch schon probiert, doch es kommt nur immer wieder diese riesige große Zahl bei der Funktion an. Hier der Code:

Code:
#include <string.h>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>

DWORD WINAPI MainFuncThread(LPVOID lpParam) //Main Thread aufrufen(Wird per Thread aufgerufen!)
{
int DLLNumber = (int)lpParam; //lpParam in Int umwandeln.
_tprintf (TEXT("Shout here from Thread %i\n"),DLLNumber); // Gibt hier eine riesige Zahl aus
// ...
return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
int DLLNumber = 0;
CreateThread(NULL,0,MainFuncThread,&DLLNumber,NULL,NULL);

DLLNumber++;

// ...
CreateThread(NULL,0,MainFuncThread,&DLLNumber,NULL,NULL);

return 0;
}

Probiert es ruhig selber mal aus es kommt einfach immer nur eine riesige Zahl raus

PS: Ich glaube nicht das es an der übergabe liegt sondern an "int DLLNumber = (int)lpParam; //lpParam in Int umwandeln." Der COmpiler gibt da eine Warnung von wegen Zeigerverkürzung aus.

?: Das problem lag in der Funktion und zwar da mit der Zeiger-Verkürzung so gibt er den richtigen Wert aus:
Code:
DWORD WINAPI MainFuncThread(LPVOID lpParam) //Main Thread aufrufen(Wird per Thread aufgerufen!)
{
int* DLLNumber = (int*)lpParam; //lpParam in Int umwandeln.
int Number = *DLLNumber;
_tprintf (TEXT("Shout here from Thread %i\n"),Number); 
// ...
return 0;
}
Danke nochmals der Hilfe
 
Du stellst den ZEIGER, NICHT jedoch das, WORAUF der zeigt, dar!

SO bekommst Du den Zeiger (also einen Wert irgendwo im Bereich von 1Milliarden - falls Du ein 32-bit-System benutzt):
Code:
int* DLLNumber_Pointer = (int*)lpParam;
// Typecastings solltest Du ERST RECHT NUR dann anwenden, wenn Du TATSÄCHLICH mit tiefstem logischem Verständnis BEGRIFFEN hast,
// was das bewirken SOLL... Der Compiler "DENKT" sich durchaus etwas dabei, wenn er Dir das Benutzen eines Pointern als "int" ankreidet!
// Obwohl: Er kreidet es Dir natürlich auch an, den "void*" als "int*" zu verwenden, also brauchst Du den Typecast zwingend... Egal...
// GLAUBE ihm ruhig, solange Du es nicht besser kannst!
// NAMEN von Variablen SOLLTEST Du an deren Zweck festmachen, HIER also daran, daß es ein POINTER IST!

// und DANN, falls Du eine KOPIE der DLLNumber anlegen möchtest:
int DLLNumber = *DLLNumber_Pointer;
tu_was(DLLNumber);
// oder falls Du die DLLNumber als globalen Wert direkt aus dem Thread heraus manipulieren möchtest
// (wozu Du dann eine Zugriffssynchronisation brauchen wirst):
tu_was(*DLLNumber_Pointer);

SO dagegen bekommst Du DAS, WORAUF der Zeiger zeigt (also bei Dir die fortlaufend aufsteigende Nummer):
Code:
int DLLNumber = *(int*)lpParam;
//lpParam in einen "Int*" (sprich "int pointer" umwandeln - weil der Compiler void als wirklich "nichts zu tun" ansehen würde
// - und Du WEISST, daß Du einen "int*" übergeben hast!)

Du bist aber schon mal auf dem richtigen Weg.
Immerhin funktioniert es korrekt.
Nur ist die momentan korrekte Funktion noch nicht die, die Du tatsächlich haben willst.

----

Was ich zur eigenen Unterstützung machen würde (manchmal sind Namenskonventionen über Prefixe ganz nützlich, um das eigene Denken zu unterstützen - und diese Sache ist üblich, also vielfach bewährt):

Versieh Deine Pointer-Variablen mit einem Prefix "p", also:
Code:
int* pDLLNumber = (int*)lpVoid

So wirst Du immer dran erinnert, daß Du da einen POINTER in der Hand hast, der IRGENDWOHIN ZEIGT statt selbst den Zielwert darzustellen. Der also eine Art Fernrohr AUF den Zielwert ist. Den Du als Stange benutzt, über die Du den Zielwert anstößt. Um mal ein paar Betrachtungsvarianten anzuregen.

Während es zu anderen übertriebenen Prefix-Schmeißereien durchaus kontroverse Auffassungen gibt, ist dieses Prefix weitreichend anerkannt, weil der Umstand, einen Zeiger statt den eigentlichen Zielwert in der Hand zu haben, gern in Vergessenheit gerät und eine krass andere Herangehensweise verlangt (daß hier dann eine Synchronisation notwendig ist, ist auch nur EIN Sonder-Aspekt unter vielen möglichen...)

Und nochmal ein Tipp: Gehe schrittweise vor!
ERST die Sache mit den Pointern begreifen, DANN sowas wie Threads!
Threads sind größere Elemente in der Prozeßverwaltung, deren Sinn ganz wesentlich darin besteht, von gemeinsamen größeren Aufgaben kleine Anteile losgelöst vom Rest eines Systems zu erledigen. DAZU aber MUSS ein Thread sich seinen Anteil an zu bearbeitenden Daten aus einem gemeinsamen (globalen) Datenbestand herausgreifen und die Ergebnisse wieder in den gemeinsamen Datenbestand zurückschreiben. Es sei denn, Du willst Threads nur rein zum akademischen Basteln erzeugen. Und FÜR jenes Hin- und Hertransportieren von Daten in/aus globalen Datenbeständen wirst Du ziemlich zwingend mit Pointern hantieren müssen...

Links dazu:

http://www.cplusplus.com/doc/tutorial/pointers.html
http://www.gidforums.com/t-6802.html
http://boredzo.org/pointers/

----

P.S.: Hatte übersehen, daß "cr4ven" das Problem schon gelöst hatte. Vielleicht helfen die Erklärungen ja jemand anderem... Viel Erfolg jedenfalls beim Basteln!
 
Zurück
Oben