Eigene Console
-
gast155 schrieb:
Das ist eigentlich auch alles, aber es wird nur eins geöffnet.
Du hast bei den Parametern für CreateProcess einmal NULL zuwenig vor dem false, dafür einmal zu viel nach CREATE_NEW_CONSOLE.
-
STARTUPINFO.cb muss vor dem Aufruf gefüllt werden.
Wenn es weiterhin nicht klapt, mal den Fehler-Code ermitteln:GetLastError
-
Hallo,
ich habe ein wenig weiter gemacht. Jetzt kriege ich den Fehler 'Run-Time Check failure #3 - the variable 'zeiger' is being used without being initialized'.
Obwohl ich den Zeiger initialisiert habe.
Das sit der Code.
#include <iostream> #include <Windows.h> #include <conio.h> using namespace std; struct Status{ int stat; // 1=Stopp, 0=Start }; int main (){ Status *zeiger; zeiger->stat=0; // Initialisiert !? cout << "Der Main Prozess " << endl; STARTUPINFO si; ZeroMemory(&si, sizeof(si)); PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); si.dwFlags=STARTF_USEPOSITION | STARTF_USESIZE; //Wird gebraucht sonst keine // änderungen an der Größe und Position des Fensters si.dwX = 10; // X-Position(X-Achse) an der das Fenster gezeichnet werden soll si.dwY = 380; // Y-Position(Y-Achse) si.dwXSize = 520; // Breite si.dwYSize = 100; // Höhe if(!CreateProcess(NULL, "arbeiter", NULL, NULL, false, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi) ) { cout << "Prozess konnte nicht erzeugt werden, Fehler: " << GetLastError() << endl; } bool ende=false; while (true) { if(_kbhit()){ char c=_getche(); switch(c){ case 'q': ende=true; break; case 'b': zeiger->stat=1; break; default: break; } } if(ende==true)break; // Endlose WHILE-Schleife verlassen } cout << "Main Prozess beendet ..." << endl; while(!_kbhit()); WaitForSingleObject(pi.hProcess,INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 0; } ////////////////////////////////////////////////////////////////////////// ///////////////////////////Arbeiter-Prozess/////////////////////////////// ////////////////////////////////////////////////////////////////////////// #include <iostream> #include <Windows.h> #include <conio.h> using namespace std; struct Status{ int stat; }; int main() { Status *zeiger; cout << "Arbeiter Prozess gestartet... " << endl; for(int i=0;i<4;i++) // einfach zum belasten des Prozessors { if(zeiger->stat==1) break; cout << "noch " << i << " mal" << endl; for(int i; i<=10000; i++) { cout << i << endl; Sleep(100); } } cout << "Kind-Prozess beendet ..." << endl; while(!kbhit()); return 0; }
-
Status *zeiger = NULL;
Nun ist der Zeiger vom Typ Status inialisiert.
zeiger->stat kann nicht funktionieren, da zeiger nur ein Zeiger vom Typ Status ist und nicht mehr.
Es gibt keine definierte Variable vom Typ Status.
-
ich weis nicht was du damit bezwecken willst,
aber einen zeiger inizialisiert man nicht so wie du es gemacht hast.ein zeiger.... zeigt auf etwas... deshalb heist er Zeiger...
und normalerweise zeigt ein zeiger auf eine Adresse bzw. Adressraum im Heap.in diesem Adressraum stehen dann werte für eine strucktur zB.
also entweder
Status *zeiger = NULL;
oder aber
Status *zeiger = new Status;<--[EDIT] für lauter Zeiger...
schwachsinn geschrieben
da du aber nicht weist was ein zeiger macht, bzw. wofür er gut ist. lass es mit einem zeiger zu arbeiten. denn ein zeiger den du nicht löscht nachdem du ihn verwendet hast, verursacht lochfras in der Birne deines PC. (memory leaks!)
[Edit]
@Shiba
dein zeiger macht gar nichts, er zeigt auf nichts und kann nicht verwendet werden, das programm wird abstürzen.ich sagts nochmal...
EIN ZEIGER MUSS AUF ETWAS ZEIGEN UND ZWAR AUF EINEN ADRESSRAUM IM HEAP SONST KACKT DEIN PROGRAMM AB.
-
@@rT!f@Ct
Es ging um eine reine Initialisierung des Zeigers.
Die Sätze danach klären dann den Rest oder?
Ansonsten warum brüllst Du?@Gast15
Hier ist kurz erklärt, wie es mit Zeigern funktioniert:
http://de.wikibooks.org/wiki/C-Programmierung:_Zeiger#Beispiel
-
ich brüll nicht,aber die nächste post mit mein programm stürzt ab, ist mit
Status *zeiger = NULL;
vorprogrammiert.
es sollte nur verdeutlichen das es wichtig ist den zeiger auf etwas zeigen zu lassen und das eine reine inizialisierung mit null nichts bringt.
das programm würde in zeile 14 und 5814: zeiger->stat=0; // Initialisiert !? 58: zeiger->stat=1;
abstürzen
-
Es ging mir auch nur um diesen Fehler
Run-Time Check failure #3 - the variable 'zeiger' is being used without being initialized'Und ich sag ja auch nicht, dass das Programm dann läuft.
Und habe auch nichts gegen abstürzende Programme mit Null Pointer Exception.
Bin auch der Meinung, sowas muss mal mal gemacht haben. Ist ein Erlebnis.
Aber wenn man schon durch die Gegend pointert, ist es ja auch eine Überlegung wert seine Zeigervariablen vor Nutzung gegen Null zu checken.Gast15 braucht in seinem Beispiel diesen Zeiger auch nicht. Er braucht nur eine Variable vom Type Status zu definieren und gut ist.
-
drum schrieb ich ja
@rT!f@Ct schrieb:
da du aber nicht weist was ein zeiger macht, bzw. wofür er gut ist. lass es mit einem zeiger zu arbeiten
-
@rT!f@Ct schrieb:
EIN ZEIGER MUSS AUF ETWAS ZEIGEN UND ZWAR AUF EINEN ADRESSRAUM IM HEAP SONST KACKT DEIN PROGRAMM AB.
Also wenn Du schon so schreist:
Wo steht denn, dass ein Zeiger auf etwas im HEAP zeigen muss?
-
Danke für die Anrworten, dass klärt für mich dann einiges.
Ich hatte versucht ein Programm nach zu vollziehen, den ein Prof geschrieben hatt.
Er benutzt dort auch ein zeiger auf eine Struktur, bei Ihm funktionierts allerdings.
Shiba:
Gast15 braucht in seinem Beispiel diesen Zeiger auch nicht. Er braucht nur eine Variable vom Type Status zu definieren und gut ist.
Diese Frage habe ich mir auch gestellt das würde ja einiges vereinfachen, hier ein Auschnitt, wie gesagt bei Ihm Kompiliert und läuft es, ich sehe jetzt den Unterschied nicht.
//------------------------------------------------------// // Kontrolle eines Systems von // // Prozessen // //------------------------------------------------------// // keine Synchronisation der Zugriffe auf das // // shared memory ! // //------------------------------------------------------// #include <Windows.h> #include <stdio.h> #include <conio.h> const int N = 5; // anzahl Arbeiter maximal 5 // --- Status der Arbeiter ------------------ struct STATUS { double x; double y; int count; int stat; // 0: arbeiten 1: halten }; // --- geordneter Exit ---------------------- void MeinExit(); void main() { // --- init ----------------------------- printf(" --- Kontrolle ----- \n"); HANDLE hProc[N]; STATUS *ProcStat; // --- exit Handler --------------------- int nRet = atexit(MeinExit); if(nRet) { printf("Der Exit Handler konnte nicht gesetzt werden\n"); } if(N > 5) { printf(" Die Anzahl Prozesse kann maximal 5 sein !\n"); MeinExit(); } // --- shared memory anlegen ----------- HANDLE hMap = CreateFileMapping( INVALID_HANDLE_VALUE, // Shared Memory NULL, PAGE_READWRITE, // Lese-/Schreibzugriff 0, // Grösse: High Wert 1000, // Grösse: Low Wert "Status"); // der Name des Objekts if(hMap == 0) { printf(" File Mapping konnte nicht erzeugt werden %d \n",GetLastError()); MeinExit(); } // --- einen Pointer ins SharedMemory besorgen -- ProcStat = (STATUS *)MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,1000); if(ProcStat == NULL) { printf(" Pointer in SM fehlerhaft \n"); CloseHandle(hMap); MeinExit(); } // --- Prozesse aufsetzen ------------- STARTUPINFO si; ZeroMemory(&si,sizeof(si)); si.dwFlags = STARTF_USEPOSITION | STARTF_USESIZE; si.dwX = 10; si.dwY = 300; si.dwXSize = 320; si.dwYSize = 300; PROCESS_INFORMATION pi; ZeroMemory(&pi,sizeof(pi)); char cmd[200]; // Ist der Buffer für den // den sprintf() aufruf // --- N Prozesse starten -------------- for(int i=0; i<N; i++) { sprintf(cmd,"arbeiter.exe %d %d",i,i); // Kommandozeile bauen si.dwX = 10 + i*(300 + 50); BOOL bRet = CreateProcess(NULL, cmd, // Kommandozeile NULL, NULL, false, // keine Handles vererben (wird hier nicht gebraucht) CREATE_NEW_CONSOLE, // neues Fenster erzeugen NULL, NULL, &si, // Startup Informationen &pi); // Prozess/Thread Handles if(bRet) hProc[i] = pi.hProcess; // Handle merken, bei OK else printf(" der Prozess %d konnte nicht gestartet werden %d \n",i,GetLastError()); } // === Kontrollschleife ================== bool stop = false; int Proc_Nr = 0; while(true) { // --- Eingabe ----------------------- if(_kbhit()) { char c = _getche(); // 1 einziges Zeichen wird abgefragt, kein Echo, // dass bedeutet der Benutzer sieht seine Eingabe nicht printf("\n"); // --- das brauche ich, um N variabel zu halten //if(c>='0' && c<='5') { //Proc_Nr = c & 0x0f; //c = 'P'; //} //Scheint kein großen unterschied zu machen, deswegen // auskommentiert switch(c) { case 'q': // alles stoppen stop = true; break; case 's': // Status ausgeben for(int i=0; i<N; i++) { printf(" Prozess: %d x: %+.5e y: %+.5e count: %d status: %d \n",i,(ProcStat+i)->x,(ProcStat+i)->y,(ProcStat+i)->count,(ProcStat+i)->stat); } break; case 'P': // Prozess 0 anhalten if((ProcStat+Proc_Nr)->stat == 0) (ProcStat+Proc_Nr)->stat =1; else (ProcStat+Proc_Nr)->stat =0; break; default : break; } } // --- Status ------------------------ if(stop) // Endlose WHILE-Schleife verlassen break; } // === Ende ============================== printf(" Ende ...... \n"); // --- aufräumen ------------------------- // --- Prozesse beenden ----------------- for(int i=0; i<N; i++) if(hProc[i] != INVALID_HANDLE_VALUE) TerminateProcess(hProc[i],0); // --- SM freigeben --------------------- UnmapViewOfFile(ProcStat); CloseHandle(hMap); } // // --- Exit Handler ------------------------ // void MeinExit() { // --- auf Taste warten ---------------- printf(" weiter mit beliebiger Taste ....\n"); while(!_kbhit()); // --- System Exit --------------------- exit(-1); }
-
@gast15
kuck in zeile 59 dort wird der zeiger inizialisiert@Belli
wer lesen kann ist klar im vorteil....ich schrieb:
ich brüll nicht,
&
und normalerweise zeigt ein zeiger auf eine Adresse bzw. Adressraum im Heap.somit sollte deine frage geklärt sein
-
@rT!f@Ct schrieb:
ich sagts nochmal...
EIN ZEIGER MUSS AUF ETWAS ZEIGEN UND ZWAR AUF EINEN ADRESSRAUM IM HEAP SONST KACKT DEIN PROGRAMM AB.int foo() { int i = 0; int* p = &i; *p = 10; return i; }
Muss sagen ich seh da kein new und konsorten aber das programm "KACKT" nicht ab o0
-
@C0de4Fun
wenn auch du dich nur an dingen hochziehen kann die schon laaaange revidiert wurden, freut es mich das ich dir behilflich sein konnte einen hochzukriegenaber nochmal für die ganz blinden
ich schrieb:
...zeiger auf eine Adresse...
nix anderes macht deine funktion
-
Mein SharedMemory funktioniert irgendwie nicht sitze schon seit einpaar stunden dran, und bin echt genervt von dem ganzen -> Die Benutzerabfragen bringen den Kindprozess nicht zum stoppen.
Und ist es möglich dieses Vorhaben(Kind P durch Main P gesteuert) auch ohne zeiger umzusetzen? Wenn ja wie?
#include <iostream> #include <Windows.h> #include <conio.h> using namespace std; struct Status{ int stat; }; int main (){ Status *zeiger; cout << "Der Main Prozess " << endl; // ---------------------- File Mapping -------------------------------- // HANDLE map = CreateFileMapping(INVALID_HANDLE_VALUE,0,PAGE_READWRITE,0,1000,"Status"); if(map==0){cout << "File MApping konnte nicht erzezugt werden, Fehler " << GetLastError() << endl;} zeiger = (Status *)MapViewOfFile(map,FILE_MAP_ALL_ACCESS,0,0,1000); if(zeiger==NULL){cout << "Shared Memory Fehlerhaft, Fehler " << GetLastError() << endl; CloseHandle(map);} // ---------------- Kind-Prozess erzeugen ------------------------------ // STARTUPINFO si; ZeroMemory(&si, sizeof(si)); PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); si.dwFlags=STARTF_USEPOSITION | STARTF_USESIZE; //Wird gebraucht sonst keine // änderungen an der Größe und Position des Fensters si.dwX = 10; // X-Position(X-Achse) an der das Fenster gezeichnet werden soll si.dwY = 380; // Y-Position(Y-Achse) si.dwXSize = 520; // Breite si.dwYSize = 100; // Höhe if(!CreateProcess(NULL, "arbeiter", NULL, NULL, false, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi) ) { cout << "Prozess konnte nicht erzeugt werden, Fehler: " << GetLastError() << endl; } bool ende=false; while (true) { if(_kbhit()){ char c=_getche(); switch(c){ case 'q': ende=true; break; case 'b': zeiger->stat=1; break; default: break; } } if(ende==true)break; // Endlose WHILE-Schleife verlassen } cout << endl << "Main Prozess beendet ..." << endl; while(!_kbhit()); UnmapViewOfFile(map); WaitForSingleObject(pi.hProcess,INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 0; ///////////////////////////////////////////////////////////////////// ////////////////////////////////AP////////////////////////////////// /////////////////////////////////////////////////////////////////// #include <iostream> #include <Windows.h> #include <conio.h> using namespace std; struct Status{ int stat; }; int main() { Status *zeiger; // ------------------------ SharedMemory ---------------- // HANDLE map=OpenFileMapping(FILE_MAP_ALL_ACCESS,false,"Status"); if(map==0){cout << "Fehler " << GetLastError() << endl;} zeiger = (Status *)MapViewOfFile(map,FILE_MAP_ALL_ACCESS,0,0,1000); if(zeiger==NULL){cout << "Noch ein Fehler, Fehler " << GetLastError() << endl; CloseHandle(map);} cout << "Arbeiter Prozess gestartet... " << endl; while(true){ if(zeiger->stat==1)break; for(int i=0; i<=100; i++) { cout << i << endl; Sleep(100); } } cout << "Kind-Prozess beendet ..." << endl; while(!kbhit()); UnmapViewOfFile(map); return 0; } }
-
Korrekterweise müsstest Du für "Status* Zeiger" ein "volatile" verwenden...
-
Was würde das volatile den an dem Problem ändern?
Ist es wegen dem Struct, oder wie? Eine Lösung wäre sehr hilfreich.
-
Jochen Kalmbach schrieb:
Korrekterweise müsstest Du für "Status* Zeiger" ein "volatile" verwenden...
Eher für "int stat;", oder nicht?
-
gast15 schrieb:
Mein SharedMemory funktioniert irgendwie nicht
Bei mir funktionieren Deine Programme ohne Änderung, so wie Du sie hier zuletzt gepostet hast - allerdings zählt arbeiter immer erst bis 100 zu Ende, weil der Status ja immer nur abgefragt wird, wenn die for-Schleife einmal ganz bis 100 gezählt hat ...