Speicher Freigabe von strtok

Hallo zusammen,

ich bin gerade am optimieren meiner Funktionen da Speicherknappheit herrscht.

Wenn ich folgende Funktion aufrufe sind gleich mal 126 Byte verschwunden.

Die 126 byte ist die Größe der m_pchRequest Variable

char* classWebServer::getValueFromUrl(char* pcID) {
  char *ptr;
  char *pcBuf = NULL;
  int iFound = 0;

  char *pcUrl = (char *)malloc(strlen(m_pchRequest)+1 * sizeof(char));
  memset(&pcUrl[0], 0, strlen(m_pchRequest)+1 * sizeof(char)); 
  strcpy(pcUrl, m_pchRequest);
  
  ptr = strtok(pcUrl, "? =&/");
  if(strcmp(ptr, "GET") == 0) {
  }

  while(ptr != NULL) {    
    ptr = strtok(NULL, "? =&/");    
    if(strcmp(ptr, "HTTP") == 0) {
      break;
    }   

    if(strcmp(ptr, pcID) == 0) {
      ptr = strtok(NULL, "? =&/");    
      pcBuf = ((char *)malloc(strlen(ptr)+1 * sizeof(char))); 
      strcpy(pcBuf, ptr);
      break;
    }    
  }   
  free(pcUrl);
  pcUrl = NULL;
  ptr = NULL;
  return pcBuf;
}

Doch warum? Wie kann ich den von strtok belegten Speicher wieder freigeben?

Vielen Dank im vorraus.

Gruß speedy

Das hat eigentlich nichts mit strtok() an sich zu tun. Das ist halt der String den du zerlegen willst. Was da natürlich gemacht wird es dass der String kopiert wird und damit gleich der doppelte Speicherplatz belegt wird. Das liegt daran, dass strtok() den String verändert und die Delimiter durch NULL ersetzt. Ich nehme mal an dass ist hier nötig, da der Original-String danach noch gebraucht wird.

Aber kann man nicht den ""HTTP" Teil auch mit strstr() suchen? Und danach strcspan() um den entsprechender Character ("? =&/") zu finden? http://www.cplusplus.com/reference/cstring/strstr/ http://www.cplusplus.com/reference/cstring/strcspn/

Danach kann man den Teil-String mit strncpy() kopieren.

Ich sehe auf den ersten Blick nicht weshalb es hier unbedingt strtok() sein müsste.

Hallo Serenifly,

vielen Dank für deine Antwort.

Du hast die Funktion richtig gelesen :o), der string soll erhalten bleiben deshalb wird eine Kopie erstellt.

Warum ich mit strtok arbeite, hmm, ist halt eine Möglichkeit, doch wenn der Speicher dann verloren ist, muss ich eine andere schreiben. Ich probiere mich mal an deiner Idee :-).

Hast zufällig einen Code Schnippsel rumliegen ;)

Gruß speedy

Gib mir mal einen Beispiel String und den Teil den du herausschneiden willst.

Hi,

Beispielstring:

GET http://192.168.177.23/?modul=micro&do=login&uname=sepp&up=123456789 HTTP 1.1

Ich suche z.B. nach modul (ist im String pcID) und Rückgabewert soll dann micro sein, usw

Der Funktion übergebe ich dann nur noch modul oder do usw und bekomme den entsprechenden Wert zurück.

Gruß und Danke für deine Hilfe speedy

Ok, was ich oben mit strtr() und HTTP gesagt habe war so falsch. Du fragst da auf das Ende des Strings ab. Dafür ist dann strtr() nicht so toll.

Aber man kann eigentlich auch gleich damit nach dem gewünschten Wert suchen:

char* getValueFromUrl(char* m_pchRequest, char* pcID)
{
	static char buffer[20];
	
	char* ptr = strstr(m_pchRequest, pcID);
	char* startPtr = ptr + strlen(pcID) + 1;
        int length = strcspn(startPtr, "? =&/");
	strncpy(buffer, startPtr, length);
        buffer[length] = '\0';
	
	return buffer;
}

Das ist jetzt erst mal ohne dynamische Speicherverwaltung, nur wegen dem Prinzip. Es ist noch keine Fehler-Behandlung drin und es deckt vielleicht nicht alle Fälle ab.

“length” kannst du dann auch auf malloc() anwenden um das dynamisch zu erzeugen.

EDIT:
Du musst auf jeden Fall abfangen wenn strstr() NULL zurückgibt! D.h. der Such-String wurde nicht gefunden.

P.S.: Es gibt calloc() um malloc() und memset() mit Null auf einmal zu machen:
http://www.cplusplus.com/reference/cstdlib/calloc/?kw=calloc

Hi :)

was soll ich sagen perfekt

char* classWebServer::getValueFromUrl(char* pcID) {
  char* ptr = strstr(m_pchRequest, pcID);
  if(ptr == NULL) {
    return NULL;
  }
  char* startPtr = ptr + strlen(pcID) + 1;
  int length = strcspn(startPtr, "? =&/");
  
  char* pcBuffer = (char*)calloc(length+1, sizeof(char));
  strncpy(pcBuffer, startPtr, length);
  
 return pcBuffer;
}

Danke nochmals für deine große HIlfe

Grüße Stefan