free(pointer) nach returnen des pointers



  • Hm... na gut stimmt. ^^
    Sollte aber jetzt nicht dramatisch sein (bitte). :p
    Ich merk grade ich hab etwas scheisse geschrieben im Code.
    Was man nicht alles tut um 0 Uhr.
    Also nochmal in richtig:

    extern char* weldstr(int ascii); //Deklaration
    
    char* somestr(int ascii) { //Definition
       *char c = (char*)malloc(sizeof(char)*2);
       *c = ascii; //Hier stand char statt c
       *(c+1) = '\0'; //Hier auch xD
       return c;
    }
    
    //Irgendwo anders im code wird die Funktion somestr aufgerufen:
    char das_a[2];
    // Gib mir ein 'A'!
    strcpy(das_a, somestr(65)); //65 = ASCII-Dezimalzahl für 'A'
    


  • Soll dir jetzt jemand die Geschichte von std::string, auto_ptr und/oder RAII erzählen (C++) oder willst du doch eher nach ANSI C verschoben werden?



  • Tuh was du für richtig hälst. |:cX
    (verschieb mich eben ^^)



  • Warum überhaupt den Speicher dynamisch allozieren, wenn die Größe doch konstant ist?;p

    char* create_string(char ascii)
    {
    	static char buf[2];
    
    	buf[0] = ascii;
    	buf[1] = '\0';
    
    	return buf;
    }
    


  • Weil darum:

    error C2057: expected constant expression
    error C2466: cannot allocate an array of constant size 0
    error C2133: 'newStr' : unknown size
    warning C4172: returning address of local variable or temporary

    Frag mich nicht wie er auf 0 kommt. Hier mal das ganze mit Array statt pointer.

    //Inserts one string into another for a length of maxNewLen chars at position
    //insAtPos. If overwrite is true, inserted String will overwrite source string
    //from position insAtPos onwards.
    const char* strins(const char* srcStr, const int maxNewLen, const char* insStr, const int insAtPos, const bool overwrite) {
    	//srcStr is the string in which we want to insert another string
    	//maxNewLen is the maximum length in chars of the resulting string
    	//insStr is the string to be inserted
    	//insAtPos indicates the position where to insert insStr into srcStr
    	//overwrite indicates whether to actually insert into or to overwrite srcStr at/from insAtPos with insStr
    	char newStr[maxNewLen+1]; //Create newStr to deposit new string in
    	int newCurPos = 0; //Counter for position
    	int srcCurPos = 0; //Counter for position
    	int insCurPos = 0; //Counter for position
    	int srcLen = (int)strlen(srcStr); //Amount of chars before '\0'
    	int insLen = (int)strlen(insStr); //Amount of chars before '\0'
    	while(newCurPos < maxNewLen) { //While not exceeding maxNewLen
    		if(newCurPos < insAtPos && srcCurPos < srcLen) { //If we are before the position to insert string at AND the source string has not already copied entirely
    			newStr[newCurPos] = *(srcStr+srcCurPos); //Copy the char from/to current position
    			       newCurPos++;          srcCurPos++; //Increase positions by one
    		} else { //Else
    			if(newCurPos < insAtPos - 1) { //If there is a gap of over 0 '\0's between current position of the new string and the position where to insert insStr
    				return newStr; //Return the string as far as it has been processed (should not randomly fill the gap)
    			}
    			break; //Exit the while-loop
    		}
    	}
    	while(newCurPos < maxNewLen) { //Enter while-loop with same condition (doing this to workaround predictable if-checks in previous loop -> increase algorithm speed)
    		if(insCurPos < insLen) { //If insStr has unprocessed chars
    			newStr[newCurPos] = *(insStr+insCurPos); //Copy them into newStr
    			       newCurPos++;          insCurPos++; //Increase positions by one
    			if(overwrite) srcCurPos++; //If srcStr shall be overwritten, increase srcCurPos to skip the corresponding char
    		} else { //Else
    			if(srcCurPos < srcLen) { //If srcStr has unprocessed chars
    				newStr[newCurPos] = *(srcStr+srcCurPos); //Copy them into newStr
    				       newCurPos++;          srcCurPos++; //Increase positions by one
    			} else { //Else
    				break; //Exit the while-loop
    			}
    		}
    	}
    	newStr[newCurPos] = '\0'; //Add null-terminator
    	return newStr; //Return the fully processed, new string
    }
    


  • Silencer4252 schrieb:

    ...
    

    Ich wollte grad ins Bett... Das geht jetz nich, weil ich nach dem Post Code-Alpträume bekomme. 😮



  • Okay, hab jetzt ein "Quick'n'Dirty"-Lösung gefunden.
    Gebe einfach eine absolute maximale Länge const int MAX_KEY = 4096 vor, und alles klappt wunderbar. 🙂
    Und wovon gibts da Alpträume zu bekommen? x3 Egal. Hier die funktionierende Version:

    //Inserts one string into another for a length of maxNewLen chars at position
    //insAtPos. If overwrite is true, inserted String will overwrite source string
    //from position insPos onwards.
    const char* strins(const char* srcStr, const int maxNewLen, const char* insStr, const int insAtPos, const bool overwrite) {
    	//srcStr is the string in which we want to insert another string
    	//maxNewLen is the maximum length in chars of the resulting string
    	//insStr is the string to be inserted
    	//insAtPos indicates the position where to insert insStr into srcStr
    	//overwrite indicates whether to actually insert into or to overwrite srcStr at/from insAtPos with insStr
    	//char* newStr = (char*)malloc(sizeof(char)*(maxNewLen+1)); //Allocate sufficient memory
    	if(maxNewLen >= MAX_KEY)
    		return 0;
    	char* newStr = new char[MAX_KEY];
    	int newCurPos = 0; //Counter for position
    	int srcCurPos = 0; //Counter for position
    	int insCurPos = 0; //Counter for position
    	int srcLen = (int)strlen(srcStr); //Amount of chars before '\0'
    	int insLen = (int)strlen(insStr); //Amount of chars before '\0'
    	while(newCurPos < maxNewLen) { //While not exceeding maxNewLen
    		if(newCurPos < insAtPos && srcCurPos < srcLen) { //If we are before the position to insert string at AND the source string has not already copied entirely
    			*(newStr+newCurPos) = *(srcStr+srcCurPos); //Copy the char from/to current position
    			         newCurPos++;          srcCurPos++; //Increase positions by one
    		} else { //Else
    			if(newCurPos < insAtPos - 1) { //If there is a gap of over 0 '\0's between current position of the new string and the position where to insert insStr
    				return newStr; //Return the string as far as it has been processed (should not randomly fill the gap)
    			}
    			break; //Exit the while loop
    		}
    	}
    	while(newCurPos < maxNewLen) { //Enter while-loop with same condition (doing this to workaround predictable if-checks in previous loop -> increase algorithm speed)
    		if(insCurPos < insLen) { //If insStr has unprocessed chars
    			*(newStr+newCurPos) = *(insStr+insCurPos); //Copy them into newStr
    					 newCurPos++;          insCurPos++; //Increase positions by one
    			if(overwrite) srcCurPos++; //If srcStr shall be overwritten, increase srcCurPos to skip the corresponding char
    		} else { //Else
    			if(srcCurPos < srcLen) { //If srcStr has unprocessed chars
    				*(newStr+newCurPos) = *(srcStr+srcCurPos); //Copy them into newStr
    				         newCurPos++;          srcCurPos++; //Increase positions by one
    			} else { //Else
    				break; //Exit the while-loop
    			}
    		}
    	}
    	*(newStr+newCurPos) = '\0'; //Add null-terminator
    	return newStr; //Return the fully processed, new string
    }
    


  • Ich verstehe dein Problem gar nicht.

    Silencer4252 schrieb:

    extern char* weldstr(int ascii); //Deklaration
    
    char* somestr(int ascii) { //Definition
       *char c = (char*)malloc(sizeof(char)*2);
       *c = ascii; //Hier stand char statt c
       *(c+1) = '\0'; //Hier auch xD
       return c;
    }
    
    //Irgendwo anders im code wird die Funktion somestr aufgerufen:
    char das_a[2];
    // Gib mir ein 'A'!
    strcpy(das_a, somestr(65)); //65 = ASCII-Dezimalzahl für 'A'
    

    Du willst den Speicherplatz wieder freigeben. Warum machst du das nicht direkt nach deinem Funtkionsaufruf?

    // Irgendwo anders im code...
    char* tmp_ptr = somestr(65);
    strcpy(das_a, tmp_ptr);
    free (tmp_ptr);
    

    Außerdem verstehe ich auch nicht, warum du nicht Chriffre's Lösung nimmst, was ist daran auszusetzen?

    Grüße



  • erneut_ schrieb:

    Soll dir jetzt jemand die Geschichte von std::string, auto_ptr und/oder RAII erzählen (C++) oder willst du doch eher nach ANSI C verschoben werden?

    Silencer4252 schrieb:

    Tuh was du für richtig hälst. |:cX
    (verschieb mich eben ^^)

    Das waren gute Hinweise, die erneut_ gebracht hat. Recherchiere nach Kapselung, std::string und RAII. Da werden Sie geholfen.

    Selbst in C kapselt man die Speicherverwaltung für dynamische Zeichenketten und hantiert nicht direkt mit char* herum. Der Unterschied ist nur, dass sich eine solche Kapselung in C jeder selbst bastelt während es sie in C++ schon vorgefertigt gibt: std::string .

    Gruß,
    SP



  • Also, das Beispiel mit somestr() hab ich nur zur Vereinfachung gemacht, um jedem
    das Verstehen der eigentlichen Funktion strins, beim Schreiben welcher ich auf
    das Problem gestoßen bin, zu ersparen.

    Das Beispiel war in so fern blöd, weil in diesem die array-Größe bekannt ist.
    Im Fall von strins() ist das ja nicht so, es sei denn man gibt ein absolutes
    maximum der Länge der Zeichenkette vor - schön ist das aber auch nicht.

    Natürlich kann ich das freeen direkt nach dem Funktionsaufruf machen, aber diese
    Lösung ist in so fern unpraktisch, dass man dann bei häufigen Aufrufen von strins()
    oder was auch immer für einer Funktion immer und immer wieder "manuell" den pointer
    freeen muss.

    Ich informier mich mal wegen Kapselunf, std::string und RAII. Danke. :o


Anmelden zum Antworten