Ich weiß , dass dies eine alte Frage, aber fast alles ist möglich in C. ein paar hackish Lösungen hier schon gibt es aber eine gültige Art und Weise zu bestimmen , ob Speicher richtig zugeordnet worden ist , ein Orakel zu verwenden , um den Platz zu nehmen malloc, calloc, realloc, und free. Auf diese Weise können Test-Frameworks (wie z. B. cmocka) Speicherprobleme erkennen (Seg-Fehler, Speicherfreigabe usw.). Sie können eine Liste der zugewiesenen Speicheradressen verwalten, während diese zugewiesen werden, und diese Liste einfach überprüfen, wenn der Benutzer Ihre Funktion verwenden möchte. Ich habe etwas sehr Ähnliches für mein eigenes Test-Framework implementiert. Ein Beispielcode:
typedef struct memory_ref {
void *ptr;
int bytes;
memory_ref *next;
}
memory_ref *HEAD = NULL;
void *__wrap_malloc(size_t bytes) {
if(HEAD == NULL) {
HEAD = __real_malloc(sizeof(memory_ref));
}
void *tmpPtr = __real_malloc(bytes);
memory_ref *previousRef = HEAD;
memory_ref *currentRef = HEAD->next;
while(current != NULL) {
previousRef = currentRef;
currentRef = currentRef->next;
}
memory_ref *newRef = (memory_ref *)__real_malloc(sizeof(memory_ref));
*newRef = (memory_ref){
.ptr = tmpPtr,
.bytes = bytes,
.next = NULL
};
previousRef->next = newRef;
return tmpPtr;
}
Sie müßten ähnliche Funktionen für calloc, reallocund free, jede Wrapper mit dem Präfix __wrap_. Der Real mallocist über die Verwendung von verfügbar __real_malloc(ähnlich für die anderen Funktionen, die Sie einschließen). Wenn Sie überprüfen möchten, ob tatsächlich Speicher zugewiesen ist, durchlaufen Sie einfach die verknüpfte memory_refListe und suchen Sie nach der Speicheradresse. Wenn Sie es finden und es groß genug ist, wissen Sie mit Sicherheit, dass die Speicheradresse Ihr Programm nicht zum Absturz bringt. Andernfalls geben Sie einen Fehler zurück. In der Header-Datei, die Ihr Programm verwendet, würden Sie folgende Zeilen hinzufügen:
extern void *__real_malloc (size_t);
extern void *__wrap_malloc (size_t);
extern void *__real_realloc (size_t);
extern void *__wrap_realloc (size_t);
Meine Anforderungen waren ziemlich einfach, daher habe ich eine sehr grundlegende Implementierung implementiert. Sie können sich jedoch vorstellen, wie diese erweitert werden könnte, um ein besseres Tracking-System zu erhalten (z. B. ein System zu erstellen struct, das zusätzlich zur Größe den Speicherort verfolgt). Dann kompilieren Sie einfach den Code mit
gcc src_files -o dest_file -Wl,-wrap,malloc -Wl,-wrap,calloc -Wl,-wrap,realloc -Wl,-wrap,free
Der Nachteil ist, dass der Benutzer seinen Quellcode mit den oben genannten Anweisungen kompilieren muss. Es ist jedoch alles andere als das Schlimmste, das ich gesehen habe. Das Zuweisen und Freigeben von Speicher ist mit einem gewissen Aufwand verbunden, beim Hinzufügen von Sicherheit jedoch immer mit einem gewissen Aufwand.