Eigene Console



  • @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 hochzukriegen 😃

    aber 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 ...


Anmelden zum Antworten