2011-01-06 30 views
0

Ich versuche, einen Zeiger auf ein Array von Strukturen an eine Funktion übergeben. Dann lassen Sie die Funktion ein eigenes Array von Strukturen erstellen, füllen Sie sie mit Daten und überschreiben Sie dann das alte Array mit dem neuen Array.Überschreiben Array von Strukturen in C

Ich bin ziemlich sicher, dass das Problem auftritt, wenn ich versuche, den Speicher zu überschreiben. Ich denke, dass ich entweder die falsche Methode verwenden könnte, um den Speicher zu überschreiben (sollte ich die Speicherfunktionen verwenden?), Oder ich könnte versuchen, das falsche Ding zu überschreiben. Ich bin mir nicht ganz sicher, was ich falsch mache. Wenn mir jemand in die richtige Richtung zeigen könnte, wäre ich sehr dankbar; Ich habe mir jetzt schon drei Stunden die Haare aus dem Kopf gezogen.

Struct:

typedef struct 
{ 
     char command; 
     int argc; 
     char* argv[]; 
}cmd; 

Code:

int main(int argc, char *argv[]) 
{ 
    [... irrelevant code] 
    cmd cmdv[count]; 
    cmd* cmdv_ptr = &cmdv[0]; 
    dissectCmd(cmdstr, cmdv_ptr); 
    printf("%i", cmdv[0].argc); 
    return 0; 
} 

void dissectCmd(char* str, cmd* cmdv) 
{ 
    [... irrelevant code] 
    cmd cmds[count]; 
    int i = 0; 
    for(i = 0; i < count; i++) 
    { 
     cmd next; 
     next.command = 'u'; 
     next.argc = 100; 
     cmds[i] = next; 
    } 
    cmdv = cmds; 
} 
+0

cmd cmds [count] ist eine lokale VLA-Array, nicht wahr? Auch wenn Sie cmd ** cmdv und * cmdv = cmds übergeben, wird es nicht funktionieren. – Nyan

Antwort

3

Sie sind nicht die Speicher zu überschreiben - die Anweisung cmdv = cmds nur Kopien der Zeiger (CMDV Punkt bei cmds machen.) Wenn Sie möchten, kopieren Sie tatsächlich den Speicher, Sie brauchen memcpy(cmdv, cmds, count * sizeof(cmd));

+0

Es funktioniert, danke! – Lienau

+0

... oder Sie könnten einfach 'cmdv [i] = next;' in der Schleife machen und ganz auf 'cmds' verzichten. – caf

+0

@caf, könnte funktionieren, aber nur, wenn es keine vorzeitigen Rückgaben oder Ausnahmen innerhalb dieser Schleife geben wird. Andernfalls könnte es zu einem teilweise überschriebenen Array kommen, was nicht immer gewünscht ist. –

-1

Ich bin mir nicht sicher, aber versuchen Sie,

zu deklarieren

Leere dissectCmd (char * str, cmd * CMDV)

als

Leere dissectCmd (char * str, cmd ** CMDV)

Ändern

cmdv = cmds;

zu

(* CMDV) = &cmds;

und aktuelle Anruf von Haupt Ändern der nun

dissectCmd ist (cmdstr, cmdv_ptr);

zu

dissectCmd (cmdstr, & cmdv_ptr);

Wenn Sie dies tun, verlieren Sie die Adresse vollständig an das alte Array und erstellen ein Speicherleck. es sei denn, Sie bereits in Ihrem zweiten frei [... irrelevante Code] Passage :)

+0

Richtig, das wird nicht funktionieren .. Sie sollten sich Chris Dodds Lösung anschauen. Meine Version funktioniert möglicherweise, wenn Sie printf ändern ("% i", cmdv [0] .argc); zu printf ("% i", (* cmdv_ptr) [0] .argc); D: – davogotland

+0

Vielen Dank für Ihren Vorschlag – Lienau

+0

Dies wird cmdv_ptr im Hauptbaum baumeln lassen, zeigt auf den Speicher für die lokalen cmds in DissectCmd Stack-Frame, die freigegeben wurde, wenn DissectCmd zurückgegeben –