2016-09-05 6 views
2

Ich schreibe ein R-Paket, das ein C-Skript aufruft. Das C-Skript verwendet eine Struktur mit einer dynamisch bestimmten Länge: die Länge des Arrays forest->edges auf den Daten abhängig von R. bestandenDynamische Speicherzuweisung in C-Funktionen aus R-Sprache aufgerufen

typedef struct { 
    unsigned int n_edge; 
    ... 
    unsigned int max_node; 
    unsigned int edges[]; 
} forest; 

forest * forest_new (unsigned int *n_edge) { 
    forest *f = malloc(sizeof(forest) + (2 * *n_edge * sizeof(int))); 
    f->n_edge  = *n_edge; 
    ... 
    f->max_node = 0; 
    return f; 
} 

Der Code läuft erfolgreich in C, aber stürzt ab, wenn ein R-Anruf auslöst forest_new. anstelle von malloc/calloc Meine Vermutung ist, dass die Crash-Ergebnisse aus Speicherzuweisung, und in der Tat die R manual erwähnen alternative Mittel zum Zuweisen von Speicher (z R_alloc, Calloc), die threadselsewhere vorzuschlagen scheint verwendet werden soll.

So Teil 1 der Frage ist, wenn Anrufe zu malloc/calloc sollte oder müssen durch R-Safe-Äquivalente (vielleicht sind sie irrelevant für mein Problem?). Teil 2 der Frage ist, wie die R-Safe-Funktionen mit Strukturen umgehen können, deren Länge dynamisch bestimmt wird.

Antwort

1

Sie können malloc/calloc und free in Paketen verwenden, um Speicher zuzuordnen und freizugeben, aber Sie müssen wie in jeder C-Anwendung nicht genügend Speicherfehler verarbeiten. Sie können Calloc/Free/Realloc verwenden, die von R zur Verfügung gestellt werden, und dann werden Sie den Fehler in der "R-Weise" (ein R-Fehler, wenn nicht genügend Arbeitsspeicher) behandelt. Mit der Funktion R_alloc können Sie temporäre Daten zuweisen, die automatisch freigegeben werden, wenn Ihre externe Funktion beendet wird (wenn Sie zu R zurückkehren, handelt es sich um eine stackbasierte Zuweisung).

R interessiert nicht, ob Ihr C-Code Strukturen mit dynamisch bestimmter Länge verwendet (flexible Arrays), R greift überhaupt nicht auf Ihre Struktur zu.

Wenn Sie weitere Hilfe benötigen, veröffentlichen Sie ein eigenständiges Beispiel oder geben Sie weitere Informationen zum Fehler an. Vielleicht ist es auch eine Überprüfung wert n_edge hat einen korrekten/gesunden Wert in forest_new.

Verwandte Themen