2012-05-27 9 views
5

Ich habe das seit Stunden versucht, und google all die Dinge, an die ich denke, aber ich werde verrückt.Zeiger innerhalb des gemeinsamen Speichersegments

Ich habe eine Struktur:

typedef struct { 
    int rows; 
    int collumns; 
    int* mat; 
    char* IDs_row; 
} mem; 

Ich weiß nicht, die Größen der int * (eine Matrix) und char *, bis später.

Wenn ich schaffe ich den gemeinsam genutzten Speicher wie folgt aus:

mem *ctrl; 
int size = (2 + ((i-1)*num_cons))*sizeof(int) + i*26*sizeof(char); //I have the real size now 
shmemid = shmget(KEY, size, IPC_CREAT | 0666); 
if (shmemid < 0) { 
    perror("Ha fallado la creacion de la memoria compartida."); 
    exit(1); 
} 
ctrl = (mem *)shmat(shmemid, 0, 0); 
if (ctrl <= (mem *)(0)) { 
    perror("Ha fallado el acceso a memoria compartida"); 
    exit(2); 
} 

hier kein Problem. Dann gebe ich einen Wert für ctrl-> rows und collumns und weise 0 der gesamten Matrix zu.

Aber danach schreibe ich etwas in den Segmentierungsfehler char * und bam.

Debuggen des Programms Ich sah, dass beide Zeiger, Matte und IDs_row Null. Wie gebe ich ihnen die richtigen Werte innerhalb des Shared-Memory-Segments?

Ich habe versucht, den char * -Zeiger zu entfernen, nur um es zu versuchen, und dann der segmentation Fehler Fehler in dem anderen Programm, das mit dem Shared Memory verbunden ist und überprüft nur die Werte innerhalb der Matrix (Prüfung -> Zeilen und -> collumns war succesfull)

Antwort

5
ctrl = (mem *)shmat(shmemid, 0, 0); 

Dies weist nur gültig Speicher an den ctrl Zeiger, nicht zu ctrl->mat oder ctrl->IDs_row.

Sie wollen wahrscheinlich:

mem *ctrl; 
shmemid = shmget(KEY, sizeof(ctrl), IPC_CREAT | 0666); 
//allocate memory for the structure 
ctrl = (mem *)shmat(shmemid, 0, 0); 

//allocate memory for the int* 
shmemid = shmget(KEY,((i-1)*num_cons))*sizeof(int), IPC_CREAT | 0666); 
ctrl->mat = (int*)shmat(shmemid, 0, 0); 

//allocate memory for the char* 
shmemid = shmget(KEY,i*26*sizeof(char), IPC_CREAT | 0666); 
ctrl->IDs_row = (char*)shmat(shmemid,0,0); 
+0

Vielen Dank! Ich hatte nie daran gedacht, das Shmget für jeden Zeiger zu machen. (Ich verstehe nicht einmal, wie das funktioniert, den gleichen Aufruf, aber "Casting") Jetzt gibt es ein Problem mit der zweiten Ganzzahl in der Struktur, die "Spalten". Ich gebe dort eine "1" in einem Prozess und der andere Prozess liest es als 62045 oder so ähnlich. Ich habe versucht, sizeof (ctrl) zu sizeof (Männer) und 2 * sizeof (int) + sizeof (int *) + sizeof (char *) zu ändern, aber kein Glück. – Knudow

+0

Entschuldigung, ich habe die Nachricht gesendet und dann bearbeitet. Kannst du mir ein bisschen mehr helfen? Ich habe jetzt ein Problem mit der zweiten Ganzzahl in der Struktur. – Knudow

+0

@ user1420534 Bitte posten Sie eine neue Frage mit dieser neuen Ausgabe, sie scheinen nicht verwandt zu sein. –

7

Zunächst einmal absolute Zeiger in Shared-Memory-Segmente setzen ist schrecklich terible Idee - diese Zeiger würden nur in dem Verfahren eingesetzt werden, die in ihren Werten gefüllt. Shared Memory-Segmente sind nicht garantiert an die gleiche virtuelle Adresse in jedem Prozess anhängen. Im Gegenteil - sie hängen dort an, wo das System es für möglich hält, wenn shmaddr == NULL bei Anruf auf shmat() spezifiziert wird. Sie könnten die gleiche virtuelle Adresse beim Aufruf von shmat() angeben, aber es liegt an Ihnen sicherzustellen, dass in diesem Speicherbereich in alle beteiligten Prozesse nichts anderes zugeordnet ist. Dies ist in einer tragbaren Weise schwierig zu tun. Was möchten Sie am meisten tun, ist entweder:

1) Allocate ein großes Shared-Memory-Segment, das sowohl die mem-Struktur und die zwei Datenfelder aufnimmt. Dann sollten Sie keine absoluten Zeiger, sondern Zeiger relativ zum Anfang des Speicherblocks setzen und dann die Verwendung anpassen.

2) Ordnen Sie drei verschiedene gemeinsame Segmente Speicher, sondern Zeiger setzen, setzen die Shared-Memory-IDs wie shmget() zurückgegeben:

typedef struct { 
    int rows; 
    int collumns; 
    int mat_id; 
    int IDs_row_id; 
} mem; 

Wenn Sie die Matrix zugreifen müssen oder die IDs Array Einfach an die Shared Memory ID anhängen, die im entsprechenden Feld gespeichert ist.

Achten Sie jedoch darauf, dass die Verwendung desselben KEY in nachfolgenden Aufrufen von shmget() nicht das erwartete Ergebnis ergibt, es sei denn KEY == IPC_PRIVATE. Es ist am besten, einen festen Schlüsselwert für den gemeinsamen Speicherblock mit dem Deskriptor (vom Typ mem) und IPC_PRIVATE für die anderen zwei Speicherblöcke zu verwenden, ansonsten geben die drei Aufrufe den gemeinsamen Speicherblock same zurück - der erste Erstelle es und die nächsten beiden werden einfach seine ID zurückgeben, da bereits ein Block mit diesem Schlüssel existiert.

Verwandte Themen