Wie identifiziert man Orte in MATLAB, wo Daten außerhalb der Grenzen eines Arrays gespeichert werden?

8

Ich versuche, MATLAB Coder zu verwenden, um Code von Matlab in eine MEX-Datei zu konvertieren. Wenn ich ein Code-Snippet der folgenden Form habe:

%Vor%

Dann ändert sich in Matlab das Array, um das neue Element aufzunehmen, während es in der MEX-Datei einen "Index überschreitet Matrixdimensionen" -Fehler gibt. Ich erwarte, dass es viele Stellen im Code gibt, wo das passiert.

Ich möchte die MATLAB-Version des Codes ausführen (ohne den Coder zu verwenden), aber MATLAB generiert immer dann einen Fehler oder eine Warnung, wenn die Größe eines Arrays geändert wird, weil ich etwas außerhalb der Grenzen zugewiesen habe. (Ich könnte einfach die MEX-Datei verwenden und sehen, wo die Fehler auftauchen, aber dafür muss die gesamte MEX-Datei mit MATLAB Coder neu erstellt werden, jedes Mal wenn ich den Code ändere, was eine Weile dauert.)

Gibt es eine Möglichkeit, dies zu tun? Gibt es irgendeine Art von Einstellung in MATLAB, die die "automatische Größenanpassung bei Zuweisung zu einem Out-of-Bounds-Index" deaktiviert oder eine Warnung gibt, wenn dies geschieht?

    
Alex319 19.03.2015, 17:52
quelle

1 Antwort

2

BEARBEITEN: Ab Matlab 2015b hat Coder jetzt Laufzeitfehlerprüfung als Option (aus den Matlab Release Notes):

  

In R2015b können generierte eigenständige Bibliotheken und ausführbare Dateien Laufzeitfehler erkennen und melden, z. B. die Out-of-Bound-Array-Indexierung. Im   Frühere Versionen, nur generierte MEX-Laufzeit erkannt und gemeldet   Fehler.

     

Standardmäßig ist die Laufzeitfehlererkennung für MEX aktiviert. Durch   Standardmäßig ist die Laufzeitfehlererkennung für eigenständige Bibliotheken deaktiviert   und ausführbare Dateien.

     

So aktivieren Sie die Laufzeitfehlererkennung für Standalone   Bibliotheken und ausführbare Dateien:

     

Verwenden Sie in der Befehlszeile den Code   Konfigurationseigenschaft RuntimeChecks .

     

cfg = coder.config ('lib'); % oder   'dll' oder 'exe'

     

cfg.RuntimeChecks = Wahr;

     

codegen -config cfg myfunction

     

Mit der MATLAB Coder-App in den Projekt-Build-Einstellungen   Wählen Sie auf der Registerkarte Debuggen die Option Laufzeitfehlerprüfungen generieren aus   Box.

     

Die generierten Bibliotheken und ausführbaren Dateien verwenden fprintf zum Schreiben   Fehlermeldungen an stderr und Abbrechen der Anwendung zu beenden. Ob   fprintf und abort sind nicht verfügbar, Sie müssen sie angeben. Error   Nachrichten sind in Englisch.

     

Siehe Run- Zeitfehlererkennung und Berichterstellung im eigenständigen C / C ++ - Code und Eigenständigen Code generieren, der Laufzeitfehler erkennt und meldet .

Ursprüngliche Antwort: Die Antwort in den Kommentaren bezüglich der Deklaration einer Klasse, die von der doppelten Klasse abgeleitet ist, wobei die subsref-Methode überladen ist, um Wachstum zu verbieten, wäre ein guter Weg, dies zu tun.

Eine weitere einfache Möglichkeit ist es, assert -Befehle im gesamten Code (in jeder Schleifeniteration oder am Ende einer Funktion) zu streuen, um zu bestätigen, dass die Größe nicht über die zugewiesene Größe gestiegen ist.

Zum Beispiel, wenn Sie den Code in folgendem Format hatten:

%Vor%

Dies würde die Assertion fehlschlagen lassen, wenn ein Wert zugewiesen wurde, der das Array erweitert hat.

Um dies etwas aufgeräumter zu machen, könnten Sie sogar eine Funktion erstellen, die alle Variablen, die Ihnen wichtig sind, durchsucht, indem Sie die coder.target if-Anweisung erneut umschließen. Dann könntest du das über deinen Code streuen.

Es ist nicht so elegant wie das Überladen der doppelten Klasse, aber auf der anderen Seite fügt es dem kompilierten Code überhaupt keinen Overhead hinzu. Es gibt Ihnen auch keine Fehler, wenn der Overrun passiert, aber es gibt Ihnen Sicherheit, dass der Code in einer Vielzahl von Situationen gut funktioniert.

Eine andere Möglichkeit, um Zuweisungen sicherer zu machen, besteht darin, Ihre eigenen Grenzen zu setzen, indem Sie die Aufgabe in Situationen überprüfen, in denen dies angemessen ist. Ein häufiges Problem, das ich in der Aufgabe gesehen habe, geht ungefähr so. Wir haben ein zugeordnetes Array und kopieren Daten aus einem anderen Array mit einer Vektorzuweisung. Betrachten Sie zum Beispiel die folgende Situation:

%Vor%

Oh oh, genau das, was Sie in der Frage interessiert, ist passiert: Das t -Array wurde während der Zuweisung automatisch angepasst, was in MATLAB funktioniert, aber in Coder erzeugtem Code wird ein Segfault- oder MEX-Fehler verursacht. Eine Alternative besteht darin, die Leistung der Funktion end zu verwenden, um die Zuweisung sauber zu halten (aber abgeschnitten). Wenn wir die Zuweisung ändern zu:

%Vor%

Die Größe von t bleibt unverändert, aber die Zuweisung wird abgeschnitten. Die Verwendung von end ermöglicht die Überprüfung von Grenzen während der Zuweisung. In einigen Situationen kann dies eine gute Möglichkeit sein, das Problem zu beheben, und Sie können darauf vertrauen, dass die Grenzen niemals überschritten werden. In manchen Situationen ist dies jedoch sehr unerwünscht (und gibt Ihnen in MATLAB keine Fehlermeldungen) / p>

Ein weiteres hilfreiches Werkzeug, das MATLAB zur Verfügung stellt, ist im Editor selbst. Wenn Sie das %#codegen -Tag in Ihrem Code verwenden, signalisiert es dem Syntax-Checker des Editors, verschiedene Codegenerierungsprobleme hervorzuheben, einschließlich der Stellen, an denen Sie offensichtlich die Größe eines Arrays durch Indexierung erhöhen. Dies kann nicht jede Situation erfassen, aber es ist eine gute Hilfe.

Eine letzte Notiz. Wie in der Frage erwähnt, wird eine von Coder generierte MEX-Datei Ihnen zum Zeitpunkt der Zuweisung einen "Index überschreitet Matrixdimensionen" -Fehler geben und die ursprüngliche Codezeile, in der der Fehler aufgetreten ist, ordnungsgemäß verlassen und Ihnen sogar mitteilen. Eine C-Bibliothek, die aus Coder generiert wird, hat kein so gutes Verhalten oder keine Grenzen und wird ohne Diagnose vollständig segmentieren. Die Zwischenantwort besteht darin, genau das zu tun, was Sie tun, nämlich den Code als MEX auszuführen.Das ist nicht sehr hilfreich für deine Frage (wie du sagst, der Wiederaufbau der MEX kann Zeit brauchen), aber für diejenigen von uns, die für die kalte, grausame Welt des externen C-Codes kodieren, der Zwischentest der Fähigkeit, die MEX zu finden Diese Fehler sind ein Lebensretter.

Die Quintessenz ist, dass dies eine Abweichung im Verhalten zwischen MATLAB- und Coder-generiertem C-Code ist, und es kann eine Quelle bedeutender Probleme sein. In meinem eigenen Code bin ich aus genau diesem Grund sehr vorsichtig mit Array-Zugriff und Wachstum. Es ist ein Bereich, in dem ich eine Verbesserung des Coder-Tools selbst sehen möchte. Es gibt jedoch Möglichkeiten, beim Schreiben von MATLAB-Code für Coder sehr vorsichtig zu sein.

    
Tony 14.04.2015 03:13
quelle

Tags und Links