speicher von Char-arrays und andere Variablen wieder "freigeben"



  • Hallo,

    Ich wollte mal fragen wie man Char-arrays und andere variablen wieder Freigeben kann, ständig haben variablen immer die alten werte wenn sie abgefragt werden 😞



  • Das läuft jetzt nicht direkt unter "freigeben," aber schreib halt was rein.



  • Zeig mal deinen Code, reduziert auf ein kompilierbares Minimalbeispiel, damit man sieht was du genau meinst/möchtest.



  • void Handle_oschoice_request(int con, char* data)
    {
    	char eop = 0;
    	char _name[8];
    	string OSC_Data = "";
    	uint32_t type = 0, value = 0;
    	int _length = 0, offset = 0;
    	char packet[1024];
    	int _result;
    
    	_length = (sizeof(data) - 36);
    
    	type = SWAB32(PKT_RSU);
    	offset = 0;
    
    	memcpy(&_name,&data[36],_length);
    
    	cout << "File: " << _name << endl;
    	if (memcmp(OSC_WELCOME_MESSAGE,&_name,sizeof(OSC_WELCOME_MESSAGE)) == 0)
    	{
    		OSC_Data = ReadOSCFile("../OSChooser/welcome.osc");
    	}
    	else
    	{
    		if(memcmp(OSC_LOGIN_FILENAME,&_name,sizeof(OSC_LOGIN_FILENAME)) == 0)
    		{
    			OSC_Data = ReadOSCFile("../OSChooser/English/login.osc");
    		}
    
    		if(memcmp(OSC_ERR_4E28_FILENAME,&_name,sizeof(OSC_ERR_4E28_FILENAME)) == 0)
    		{
    			OSC_Data = ReadOSCFile("../OSChooser/English/00004e28.osc");
    		}
    	}
    
    	memcpy(&packet[0], &type, sizeof(type));
    	offset += sizeof(type);
    
    	offset += 4;
    	memcpy(&packet[offset], &data[8], 28);
    
    	offset += 28;
    	OSC_Data.copy(&packet[offset],OSC_Data.length());
    
    	offset += OSC_Data.length();
    	memcpy(&packet[offset], &eop,sizeof(eop));
    
    	value = SWAB32(offset);
    	memcpy(&packet[0x4], &value, sizeof(value));
    
    	_result = sendto(con, packet, offset, 0, (struct sockaddr *) &from, sizeof(from));
    
    	if (_result == SOCKET_ERROR)
    	{
    		fprintf(stderr, "send() failed: Error %d\n", WSAGetLastError());
    	}
    	else
    	{
    		cout << "sent " << _result << " bytes to Client" << endl;
    	}
    
    	OSC_Data = "";
    }
    

    Nehmen wir als Beispiel "char _name[8];"... Diese ist sozusagen zum Deklarierungs-Zeitpunkt leer (NULL), jetzt verbindet ein Rechner und sendet "\n", was besagt "zeige mir die Willkommen-seite". Danach sendet er "LOGIN", dieser Wert wird in "_name" geschrieben, überprüft und kriegt den passenden Dateiinhalt gesendet.

    nun zum Problem, verbindet ein 2ter Rechner, so kriegt er, weil die Variable "_name" noch den alten Wert ("LOGIN") hat auch die Login-Seite, statt der Willkommens-Seite 😞



  • Das ist so ziemlich komischer Code. Den richtig zu analysieren macht keinen Spaß.

    Nehmen wir als Beispiel "char _name[8];"... Diese ist sozusagen zum Deklarierungs-Zeitpunkt leer (NULL), jetzt verbindet ein Rechner und sendet "\n", was besagt "zeige mir die Willkommen-seite". Danach sendet er "LOGIN", dieser Wert wird in "_name" geschrieben, überprüft und kriegt den passenden Dateiinhalt gesendet.

    nun zum Problem, verbindet ein 2ter Rechner, so kriegt er, weil die Variable "_name" noch den alten Wert ("LOGIN") hat auch die Login-Seite, statt der Willkommens-Seite :([/quote]Das ist sehr merkwürdig, was Du da machst. Mal so ein paar Sachen, die spontan auffallen:

    int _length = 0, offset = 0;  // _lenght wird mit 0 initialisiert
    ...
    
    	_length = (sizeof(data) - 36); // _length bekommt den Wert -28 (sizeof(char*)==8 abzüglich 36)
    	_length = 0;                   // _length wird wieder zurück auf 0 gesetzt
    ...
    	memcpy(&_name,&_name,_length);  // kopiere 0 Bytes, also gar nichts von _name nach _name  :confused:
    

    Im übrigen kann _name nie NULL sein, wie Du schreibst. Ein Zeiger kann NULL sein, _name ist aber kein Zeiger sondern ein char array. Da steht immer was drin.

    Auch setzt Du am Ende der Funktion den String OSC_Data auf einen Leerstring, obwohl er im nächsten Moment eh seinen Gültigkeitsbereich verlässt und damit gelöscht wird.

    Das Du bei so einen Stil nicht mehr durchblickst, wann welche Variable welchen Wert hat, wundert mich nicht. Räum erst mal auf. Dann siehst Du entweder selbst was oder frag hier noch mal.



  • Du solltest Variablen auch erstmal Werte zuweisen, bevor du sie benutzt.

    Ein

    char _name[8] = "";
    

    reicht schon.

    Noch ein paar Fragen:
    Was soll Zeile 11?
    sizeof(data) ist meist 4 oder 8, da data ein Zeiger ist.

    Was soll Zeile 16.
    Bei memcpy dürfen sich die Speicherbereiche nicht überlappen.

    Was soll der Adressoperator bei _name?
    DEr Arrayname steht schon für die Adresse des ersten Elements.



  • Ja hatte es noch schnell korrigiert hier der aufgeräumte code ... 😕

    und nein, sizeof(data) hat bei mir die länge vom empfangenden Paket (42 Bytes)

    Aber um klarheit zuschaffen...

    int _recv()
    {
    	uint32_t retval = 0, type = 0;
    	socklen_t fromlen;
    
    	char buffer[1024];
    
    	while (true)
    	{
    		fromlen = sizeof(from);
    		retval = recvfrom(m_socket, buffer, sizeof(buffer), 0, (struct sockaddr *) &from, &fromlen);
    
    		if (retval < 0)
    		{
    			fprintf(stderr, "recvfrom() failed: error %d\n", WSAGetLastError());
    			continue;
    		}
    
    		if (retval == 0)
    		{
    			cout << "Client closed connection" << endl;
    			continue;
    		}
    
    		cout << "Received datagram "<< retval << " bytes from: " << inet_ntoa(from.sin_addr) << endl;
    
    		char Data[retval];
    
    		memcpy(&Data, buffer, retval);
    		memcpy(&type, Data, sizeof(type));
    
    		switch (SWAB32(type))
    		{
    			case PKT_NCQ:
    			{
    				cout << "NIC Card query" << endl;
    
    				Handle_driver_request(m_socket,Data,&fromlen);
    				break;
    			}
    			case BOOTP_MCO:
    			{
    				cout << "Boot file detection (over DHCP)" << endl;
    
    				Handle_BootFile_request(m_socket,Data, &fromlen);
    				break;
    			}
    			case PKT_RQU:	/* Handle OSC file Request*/
    			{
    				cout << "OSChooser File request" << endl;
    
    				Handle_oschoice_request(m_socket,Data);
    				break;
    			}
    			default:
    			{
    				break;
    			}
    		}
    	}
    
    	closesocket(m_socket);
    	WSACleanup();
    	return errno;
    }
    
    void Handle_oschoice_request(int con, char* data)
    {
    	char eop = 0;
    	char _name[8] = "";
    
    	string OSC_Data = "";
    	uint32_t type = SWAB32(PKT_RSU), value = 0;
    
    	int _length = (sizeof(data) - 36), offset = 0; /* _length = länge von Data - 36 = Länge des Dateinamen... */
    	char packet[1024];
    	int _result = 0;
    
    	memcpy(&_name, &data[36], _length); /* 36 ist die stelle wo der Dateiname anfängt */
    
    	cout << "File: " << _name << endl;
    
    	if (memcmp(OSC_WELCOME_MESSAGE,&data[36],sizeof(OSC_WELCOME_MESSAGE)) == 0)
    	{
    		OSC_Data = ReadOSCFile("../OSChooser/welcome.osc");
    	}
    	else
    	{
    		if(memcmp(OSC_LOGIN_FILENAME,&data[36],sizeof(OSC_LOGIN_FILENAME)) == 0)
    		{
    			OSC_Data = ReadOSCFile("../OSChooser/English/login.osc");
    		}
    
    		if(memcmp(OSC_ERR_4E28_FILENAME,&data[36],sizeof(OSC_ERR_4E28_FILENAME)) == 0)
    		{
    			OSC_Data = ReadOSCFile("../OSChooser/English/00004e28.osc");
    		}
    	}
    
    	memcpy(&packet[0], &type, sizeof(type));
    	offset += sizeof(type);
    
    	offset += 4;
    	memcpy(&packet[offset], &data[8], 28);
    
    	offset += 28;
    	OSC_Data.copy(&packet[offset],OSC_Data.length());
    
    	offset += OSC_Data.length();
    	memcpy(&packet[offset], &eop,sizeof(eop));
    
    	value = SWAB32(offset);
    	memcpy(&packet[0x4], &value, sizeof(value));
    
    	_result = sendto(con, packet, offset, 0, (struct sockaddr *) &from, sizeof(from));
    
    	if (_result == SOCKET_ERROR)
    	{
    		fprintf(stderr, "send() failed: Error %d\n", WSAGetLastError());
    	}
    	else
    	{
    		cout << "sent " << _result << " bytes to Client" << endl;
    	}
    }
    

    gut da meinte einer was von fragen, denn erklärt mir mal bitte jemand den unterschied zwischen:

    memcpy(&Data, buffer, retval);
     memcpy(&type, Data, sizeof(type));
    

    und dem:

    memcpy(&Data, &buffer, retval);
    memcpy(&type, &Data, sizeof(type));
    

    😞



  • LipkeGu schrieb:

    und nein, sizeof(data) hat bei mir die länge vom empfangenden Paket (42 Bytes)

    Bestimmt nicht. Gib mal sizeof(data) aus, dann wirst du sehen, dass sizeof(data) != 42 ist.



  • Hmm tatsache, das sind wirklich nur 4, das erklärt einiges warum ich keinen namen aus &_name erhalte jedoch aus &data[36] 😞

    kann mir jemand erklären wie man das richtig macht? also das ermitteln von inhalt und der länge? 😞



  • Was willst du wissen, dei Länge vom Text oder die Größe des Speicherbereichs auf den data zeigt?
    Das erste geht mit strlen .
    Im zweiten Fall musst du der Funktion einen extra Parameter spendieren.

    Oder programmiere richtiges C++ (und nutze dessen Möglichkeiten) und nicht C mit cout .

    Und nochmal zu deiner memcpy -Frage bezüglich Adressoperator:
    Das Verhalten beim Adressoperator hängt davon ab, ob deine Variablen Arrays oder Pointer sind.
    Und das sollte es auf gar keinen Fall.



  • wo wird das denn erklärt, mit dem richtigen C++ 😞



  • LipkeGu schrieb:

    wo wird das denn erklärt, mit dem richtigen C++ 😞

    In einem guten C++ Buch 😉

    Ich persönlich mag den C++ Primer von Lippman, den es aber nur auf englisch gibt. Ein deutsches Buch wäre z.B. der C++ Programmierer.


Anmelden zum Antworten