segmentation fault nach Allokierung in seperater Funktion



  • Hallo,
    ich möchte einem pointer, welchen ich in der main() deklariere, in einer seperaten Funktion Speicher(mittels malloc) und Werte zuweisen. Nach dem Aufruf dieser Funktion in der main zeigt der Pointer aber wieder auf die NULL, und gibt beim Zugriff in Zeile 35 ein Segmentation fault aus. In der Funktion receive_data selbst kommt es nicht zu einem Seg fault.
    Ich habe den Code auf das Problem reduziert und hoffe jemand kann mir bei der Behebung weiterhelfen

    # include <stdlib.h>
    # include <stdio.h>
    
    typedef unsigned char uint8_t;
    
    int receive_data(uint8_t *data){
    		uint8_t array_write[4];
    		array_write[0] = 2;
     		array_write[1] = 0x3;
    		array_write[2] = 0x18;
    		array_write[3] = 255;
    
    		uint8_t frame_length ;
    		int index;
    
    		frame_length = array_write[0];	
    
    		if((data = malloc(sizeof(*data)*(frame_length + 2))) == NULL)
    			printf("\nAllocation failed\n");
    
    		printf("\nfolgende Nachricht mit einer Länge von %u wurde empfangen: ", frame_length);
    		for(index=0; index < (frame_length + 2); index++){
    			data[index] = array_write[index];
    			printf("%u,", data[index]);
    		}
    		printf("\n\n");
    		return (0);
    }
    
    int main(){
    		uint8_t *data=NULL;
    
    		receive_data(data);
    
    		if((data[1] & 7)==3){
    			free(data);
    			printf("\nMAC - Command received\n");
    		}
    		else
    			free(data);
    
    		return 0;
    	}
    

    vielen Dank und beste Grüße
    Gerrit



  • Hallo,
    die Variable uint8_t *data ist nur innerhalb der Funktion gültig, die innerhalb der Funktion zugewiesene Adresse ist von außen nicht sichtbar.

    Du kannst entweder einen Zeiger auf einen Zeiger übergeben

    int receive_data(uint8_t **data);
    

    oder einen Zeiger zurückgeben

    uint8_t* data receive_data();
    

    Gruß,
    B.B.



  • Könnte an dem free(NULL) in main() liegen. So, wie das jetzt ist, kann receive_data() den Zeiger in main() nicht verändern, weil Argumente immer als Kopie übergeben werden. Wenn du den Zeiger in main() verändern willst, verwende am besten den Rückgabewert der Funktion, um den Zeiger von malloc() nach main() weiterzuleiten. Du könntest aber auch einen Zeiger auf den Zeiger als Argument von receive_data() benutzen.
    🙂



  • Schon mal vielen Dank für die Antworten. Die Variante mit Pointer auf Pointer finde ich eleganter. Leider kriege ich jetzt aber ein Seg fault bei der Zuweisung der Variablen in Zeile 23. Laut dbg wird der erste Werte, die 2, korrekt zugewiesen, der zweite Wert jedoch nicht mehr. Statdessen zeigt data[1] auf die NULL.
    Hier der veränderte Code:

    # include <stdlib.h>
    # include <stdio.h>
    
    typedef unsigned char uint8_t;
    
    int receive_data(uint8_t **data){
    		uint8_t array_write[4];
    		array_write[0] = 2;
     		array_write[1] = 0x3;
    		array_write[2] = 0x18;
    		array_write[3] = 255;
    
    		uint8_t frame_length ;
    		int index;
    
    		frame_length = array_write[0];	
    
    		if((*data = malloc(sizeof(**data)*(frame_length + 2))) == NULL)
    			printf("\nAllocation failed\n");
    
    		printf("\nfolgende Nachricht mit einer Länge von %u wurde empfangen: ", frame_length);
    		for(index=0; index < (frame_length + 2); index++){
    			*data[index] = array_write[index];
    			printf("%u,", *data[index]);
    		}
    		printf("\n\n");
    		return (0);
    }
    
    int main(){
    		uint8_t *data=NULL;
    
    		receive_data(&data);
    
    		if((data[1] & 7)==3){
    			free(data);
    			printf("\nMAC - Command received\n");
    		}
    		else
    			free(data);
    
    		return 0;
    	}
    


  • gGerczek schrieb:

    Schon mal vielen Dank für die Antworten. Die Variante mit Pointer auf Pointer finde ich eleganter. Leider kriege ich jetzt aber ein Seg fault bei der Zuweisung der Variablen in Zeile 23.

    [] hat eine höhere Priorität als *.



  • Ich habe jetzt auch die Prioritäten beachtet und es funktioniert jetzt einwandfrei, vielen Dank für die Hilfe.


Anmelden zum Antworten