Umgang mit Pointern



  • @_Neuling sagte in Umgang mit Pointern:

    char *p_ptr=NULL;
    
    if((p_ptr=malloc(10))==NULL)
    	printf("fail\n");
    

    Komisches Muster mit Zuweisung im if, das du da zweimal geschrieben hast.

    char *foo = malloc(42);
    if(!foo) {
        // exit / return / whatever.
    }
    


  • Ich habe den Teil eines großen Projektes und dachte zu viel Code und geschreibe schreckt eher ab.

    Im Grunde möchte ich üben einen Kommunikationsweg Daten austauschen(zur Zeit noch seriell oder ssh). Da die Datenmengen abundzu recht groß sein können(~4000Bytes), wollte ich dynamischen Speicher verwenden.

    char *p_buffer=NULL;
    	
    	if((p_buffer=malloc(1024+1))==NULL)
    		return 0;
    	
    	wr_cmd2("commando", &p_buffer);	
    	wr_cmd2("commando", &p_buffer);
    	
    	free(p_buffer);
    

    ich möchte also ich unterschiedlichen Funktionen write read Kommandos absetzen können.

    int wr_cmd2(char *cmd, char **recv_buffer){
    
    	
    	switch(COMM_METHOD)
    	{
    		case CM_RS232:
    					WriteReadComFixSize(cmd, *recv_buffer);	
    			break;
    		case CM_SSH:
    					GetAndSendInput(cmd);
    					GetAndSendInput("\n");
    					ReadAndHandleOutput_untilprompt(*recv_buffer);
    					break;
    		default: printf("Unknown communicationway!");
    	}
    
    	return 0;
    }
    

    ReadAndHandleOutput_untilprompt() ließt mit readfile aus einer pipe

    do
    {
    		printf("available: %i\n",i_BytesAvailable); 
    		if((i_BytesAvailable-i_BytesCount)<READ_BUF_SIZE+1) // have always enough memory for a readfile with full READ_BUF_SIZE(512)
    		{
    			printf("alloc! %i - %i < 512+1 = %i\n", i_BytesAvailable, i_BytesCount, i_BytesAvailable-i_BytesCount);
    			p_test=realloc(*lpBuffer, DEFAULT_BUF_SIZE+(READ_BUF_SIZE * ++i)+1);// +1 for stringnull at the end
    			if(p_test==NULL)
    			{
    				printf("can't allocate memory, abort reading!");
    				return -1;
    			}
    			printf("i=<%i> allocate memory= %i\n", i, DEFAULT_BUF_SIZE+(READ_BUF_SIZE * i)+1); 
    			*lpBuffer=p_test;
    			i_BytesAvailable=DEFAULT_BUF_SIZE+(READ_BUF_SIZE * i)+1;
    		}
    
    		if (!ReadFile(Redirect_Info.hOutputRead, *lpBuffer+i_BytesCount, READ_BUF_SIZE, &nBytesRead, NULL))
    	        {
    	    	          if (GetLastError() == ERROR_BROKEN_PIPE)
    	                 {
    	           	         printf("ERROR_BROKEN_PIPE");
    	           	         return -2;
    	                 }
    	                 else
    	                 {
    	           	         printf("error at ReadFile",);
    	           	         break;
    	                 }
    	        }
    	        //counting 
    	        i_BytesCount+=nBytesRead;
    	        printf("Bytescount: %i += nBytesRead %i\n", i_BytesCount, nBytesRead);
    		
    		*(*lpBuffer+i_BytesCount)=0;
    	        printf("strlen: %i\n",strlen(*lpBuffer));
    	    
    	}while(find_prompt(&(*lpBuffer), nBytesRead));
    

    Der Auszug ist sicherlich nicht ansatzweise korrekt, dem bin ich mir bewusst, es soll nur meine Herangehensweise darstellen.

    @swordfish: bei dem fail habe ich einen Breakpoint gesetzt, d.h. ich wäre nicht weiter gegangen im Fehlerfall.



  • Vielleicht möchtest Du einen Datentyp für Strings implementieren?

    typedef struct string_tag {
        char *data;
        size_t length;
        size_t size;
    } string_t;
    
    string_t string_create(void)
    {
        string_t string = { calloc(1, 1), 0, 1 }; // Leerer String, '\0' terminiert. length = 0, size = 1
        return string;
    }
    
    bool string_is_valid(string_t *string)
    {
        return string->data;
    }
    
    bool string_assign(string_t *dst, char const *src)
    {
        size_t new_length = strlen(src);
        if (new_length + 1 > dst->size) {
            char new_data = realloc(dst->data, new_length + 1);
            if(!new_data)
                return false;
            dst->data = new_data;
        }
        dst->size = new_length + 1;
        dst->length = new_length;
        strcpy(dst->data, src);
        return true;
    }
    
    // ...
    

    @_Neuling sagte in Umgang mit Pointern:

    @swordfish: bei dem fail habe ich einen Breakpoint gesetzt, d.h. ich wäre nicht weiter gegangen im Fehlerfall.

    Ja, ne, das Komische ist das Initialisieren mit NULL und die umständliche Zuweisung in der condition vom if.



  • Danke fürs Beispiel @swordfish, aber muss ich die Datenstruktur dann nicht genauso durchreichen mit Pointern, wie ich es im ersten Beitrag vor hatte?



  • Ja, weil du willst ja das Original verändern und nicht eine Kopie. Aber was ist das Problem dabei? Wenigstens hast Du so keine hässlichen "Doppelzeiger" mehr. Die Zauberworte heißen OOP und Kapselung.

    // edit: Ich hab' dir string_assign() oben als Bleistift implementiert. string_append() usw. ist dein Bier. string_destroy() nicht vergessen.



  • Ich vermute ich verstehe was du mir sagen möchtest, aber wenn ich die Datenstruktur in die 3.Unterfunktion befördern muss, um den prompt zu suchen, brauch ich doch genauso wieder Doppelzeiger, ich sehe noch nicht ganz den Vorteil? Vllt brauch ich ein Beispiel um es korrekt zu verstehen?



  • @_Neuling sagte in Umgang mit Pointern:

    [...] 3.Unterfunktion befördern muss, um den prompt zu suchen, [...]

    Ne, du, ich hab' keine Lust zu suchen. Code?



  • Letztes codebeispiel, letzte Zeile, find_prompt() gibt 0 zurück, wenn der prompt gefunden werden konnte.
    Edit: gut, in der letzten Funktion ist es nicht nötig by reference zu übergeben, da nicht verändert wird, dann sind in diesem Bsp zwei Unterfunktionen

    Wie gesagt, ich versuche mir eine gute Programmierstruktur anzueignen, benötige aber dabei etwas Unterstützung



  • @_Neuling sagte in Umgang mit Pointern:

    Letztes codebeispiel, letzte Zeile, find_prompt() gibt 0 zurück, wenn der prompt gefunden werden konnte.

    Ja, dann wirst Du wohl eine bool string_find(string_t const *haystack, char const *needle) schreiben müssen. strstr() ist dein Freund.

    @_Neuling sagte in Umgang mit Pointern:

    in der letzten Funktion ist es nicht nötig by reference zu übergeben, da nicht verändert wird, dann sind in diesem Bsp zwei Unterfunktionen

    Jein. Nötig nicht. Aber einen Pointer zu kopieren ist trotzdem billiger als die gesamte struct. Übergib per string_t const *.


  • Gesperrt

    @Swordfish sagte in Umgang mit Pointern:

    Vielleicht möchtest Du einen Datentyp für Strings implementieren?

    typedef struct string_tag {
        char *data;
        size_t length;
        size_t size;
    } string_t;
    

    Length und Size, WTF?
    Einer davon ist doch bestimmt überflüssig.



  • @RBS2 sagte in Umgang mit Pointern:

    Length und Size, WTF?
    Einer davon ist doch bestimmt überflüssig.

    Nur wenn der String immer nur soviel wächst wie absolut nötig. Ziemlich ineffizient.

    Selber grund warum ein std::vector<> eine size und eine capacity hat.


  • Gesperrt

    @Swordfish Okay, reservierter Speicher vs. tatsächliche Stringlänge. Alles klar. 🙂



  • @RBS2 sagte in Umgang mit Pointern:

    @Swordfish Okay, reservierter Speicher vs. tatsächliche Stringlänge. Alles klar. 🙂

    Schlauer/Braver Junge! ❤


Anmelden zum Antworten