C Pointer - Call by Value - Schreiben an eine bestimmte Adresse

hell-student

Lieutenant
Registriert
Nov. 2007
Beiträge
671
Hallo Zusammen,

ich bräuchte mal wieder eure Hilfe. Ich mappe mir per mmap einen Speicher in den Adressraum der Anwendung und möchte nun in den Speicher Daten schreiben und später lesen. Nur möchte ich nun gerne eine Funktion haben, der ich eine Adresse auf den Speicher übergebe + die Daten und dort soll alles dann gemacht werden. Leider funktioniert das nicht. Folgender Code:

Dies Funktioniert:
Code:
void *vlc_mem_baddr;
int mem_fd;

int main() {
    printf("HALLO\n");

    open_mem_device(&mem_fd);
    map_vlc_mem(&vlc_mem_baddr);

    unsigned int *vlc_mem = (unsigned int*)vlc_mem_baddr;
    *vlc_mem = 0xFFFFFFFF;
    printf("vlc_mem: %i %x %u\n", vlc_mem[0], vlc_mem[0], vlc_mem[0]);
    return 0;
}

Hierbei ist ja nur Zeile 10-12 wichtig. In Zeile 10 mache ich mir einen Pointer auf die Adresse und dereferenziere diesen in Zeile 11 sodass ich das ändern kann, was an der Speicheradresse steht.

Wenn ich aber folgendes habe, funktioniert es nicht mehr -> ich lese nur 0en:

Code:
int vlc0[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
    int vlc1[3] = { 0xFAFAFAFA, 0xFAFAFAFA, 0xFAFAFAFA};
    write_to_vlc_mem(vlc_mem_baddr, vlc0);
    write_to_vlc_mem(vlc_mem_baddr, vlc1);

    unsigned int *vlc_mem = (unsigned int*)vlc_mem_baddr;
    unsigned int i = 0;
    for (i = 0; i < 10; i++) {
    	printf("vlc_mem: %i %x %u\n", vlc_mem[i], vlc_mem[i], vlc_mem[i]);
    }

Code:
void write_to_vlc_mem(void *vlc_mem_addr_t, int vlcw[3]) {
	unsigned int i;
	volatile unsigned int *vlc_mem = (unsigned int *)vlc_mem_addr_t;

	for (i = 0; i < 3; i++) {
		*vlc_mem = vlcw[i];
		vlc_mem++;
	}

	for (i = 3; i < 6; i++) {
		vlc_mem++;
	}
}

Was mache ich hier falsch?
 
Zuletzt bearbeitet:
Eine Frage. Was ist der Sinn der 2. Schleife in deiner write_to_vlc_mem()-Funktion?
Ergänzung ()

Ansonsten kann ich an deinem Code erst mal nichts verdächtiges entdecken. Nun weiß ich allerdings nicht, wie sich die Anwendung, mit der du da interagierst, verhält. Könnte es nicht sein, daß die Anwendung selbst den Speicherbereich inzwischen wieder überschrieben hat, und du deshalb deine eben geschriebenen Werte dort nicht mehr siehst?
 
Zuletzt bearbeitet:
Die Schleife hat nur den Sinn, dass ich die Adressen überspringen möchte. Ich schreibe wohl aber jedesmal an die gleiche Adresse und daher müsste ich eigentlich mir 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF mit 0xFAFAFAFA, 0xFAFAFAFA, 0xFAFAFAFA überschreiben, wenn ich das richtig sehe, also das printen müsste eigentlich folgendes ausgaben:

0xFAFAFAFA, 0xFAFAFAFA, 0xFAFAFAFA, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0

nur bekomme ich nur 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0

Und das kann ich irgendwie nicht verstehen. Eigentlich sollte vlc_mem auf die erste Adresse im Speicher zeigen und mittels dereferenzierung düfte ich dort was hinschreiben. Ich verstehs einfach nicht :) grrr
 
hell-student schrieb:
Die Schleife hat nur den Sinn, dass ich die Adressen überspringen möchte.

Ah, du meinst, so daß der nächste Aufruf deiner write_to_vlc_mem()-Funktion dann an einer anderen Adresse beginnt zu schreiben als der erste? Na, das klappt so allerdings nicht, denn du inkrementierst nur einen lokalen Pointer innerhalb der Funktion. Für den Aufrufer bleibt der übergebene Zeiger unverändert. Da müßtest du etwas anderes tun:

Code:
void write_to_vlc_mem(unsigned int **vlc_mem_addr_t, int vlcw[3]) {
	unsigned int i;
	 
	for (i = 0; i < 3; i++) {
		**vlc_mem = vlcw[i];
		(*vlc_mem)++;
	}
	 
	for (i = 3; i < 6; i++) {
		(*vlc_mem)++;
	}
}

unsigned int* castAddress = (unsigned int*) vlc_mem_baddr;
write_to_vlc_mem(&castAddress, vlc1);
 
Ja genau, aber wie ich ja selbst meinte, wird das nicht passieren, jedoch lese ich halt nur Nullen
 
Also ich hab gerade mal alles von dir oben zusammenkopiert und es läuft wie es soll.

Code:
#include <stdio.h>

void write_to_vlc_mem(void *vlc_mem_addr_t, int vlcw[3]) {
    unsigned int i;
    volatile unsigned int *vlc_mem = (unsigned int *)vlc_mem_addr_t;
 
    for (i = 0; i < 3; i++) {
        *vlc_mem = vlcw[i];
        vlc_mem++;
    }
 
    for (i = 3; i < 6; i++) {
        vlc_mem++;
    }
}


int main() {
    char vlc_mem_baddr[40];
    int vlc0[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
    int vlc1[3] = { 0xFAFAFAFA, 0xFAFAFAFA, 0xFAFAFAFA};
    write_to_vlc_mem(vlc_mem_baddr, vlc0);
    write_to_vlc_mem(vlc_mem_baddr, vlc1);
 
    unsigned int *vlc_mem = (unsigned int*)vlc_mem_baddr;
    unsigned int i = 0;
    for (i = 0; i < 10; i++) {
        printf("vlc_mem: %i %x %u\n", vlc_mem[i], vlc_mem[i], vlc_mem[i]);
    }
    return 0;
}

Ausgabe:
Code:
vlc_mem: -84215046 fafafafa 4210752250
vlc_mem: -84215046 fafafafa 4210752250
vlc_mem: -84215046 fafafafa 4210752250
vlc_mem: 0 0 0
vlc_mem: 0 0 0
vlc_mem: 0 0 0
vlc_mem: 0 0 0
vlc_mem: 0 0 0
vlc_mem: 0 0 0
vlc_mem: 0 0 0
 
Zurück
Oben