Was bedeutet "nicht ausgerichtete Adresse error" bedeuten?
Erste von alle — sorry für die Einzelheiten. Im Allgemeinen versuche ich zu Kochen, meine Fragen zu generic "class A" - Kram nur relevante Sachen, aber ich bin mir nicht sicher, was die Ursache des Problems hier.
Ich habe eine matrix der Klasse Vorlage, die wie folgt aussieht (nur das zeigt, was ich denke, sind die relevanten Teile):
template <std::size_t R, std::size_t C>
class Matrix
{
private:
//const int rows, cols;
std::array<std::array<float,C>,R> m;
public:
inline std::array<float,C>& operator[](const int i)
{
return m[i];
}
const std::array<float,C> operator[](const int i) const
{
return m[i];
}
template<std::size_t N>
Matrix<R,N> operator *(const Matrix<C,N> a) const
{
Matrix<R,N> result = Matrix<R,N>();
//irrelevant calculation
return result;
}
//... other very similar stuff, I'm not sure that it's relevant
}
template <std::size_t S>
Matrix<S,S> identity()
{
Matrix<S,S> matrix = Matrix<S,S>();
for(std::size_t x = 0; x < S; x++)
{
for(std::size_t y = 0; y < S; y++)
{
if (x == y)
{
matrix[x][y] = 1.f;
}
}
}
return matrix;
}
Ich das Gerät getestet für die ganze Klasse, sowohl die Multiplikation und Identität Fabrik zu arbeiten scheinen in Ordnung. Aber dann benutze ich Sie in dieser Methode, die aufgerufen wird, viel mal (ich denke, dass, wenn Sie jemals schrieb einen renderer, es ist ziemlich offensichtlich, was ich versuche zu tun):
Vec3i Renderer::world_to_screen_space(Vec3f v)
{
Matrix<4,1> vm = v2m(v);
Matrix<4,4> projection = identity<4>(); //If I change this to Matrix<4,4>(), the error doesn't happen
projection[3][2] = -1.f;
vm = projection * vm;
Vec3f r = m2v(vm);
return Vec3i(
(r.x + 1.) * (width / 2.),
(r.y + 1.) * (height / 2.),
r.z
);
}
Und nach einiger Zeit und eine bestimmte Menge von random Aufrufe dieser Methode bekomme ich diese:
Job 1, 'and ./bin/main' terminated by signal SIGBUS (Misaligned address error)
Jedoch, wenn ich die Zeile ändern identity<4>()
zu Matrix<4,4>()
den Fehler nicht passieren. Ich bin neu bei C++, also muss es etwas wirklich dummes.
So, (1) was bedeutet dieser Fehler bedeutet und (2) wie kam ich zu verwalten, zu Schießen mir in das Bein?
Update: und natürlich diesen Fehler nicht reproduzieren, in der LLDB-debugger.
Update 2: hier ist, was ich bekam, nach dem ausführen des Programms durch Valgrind:
==66525== Invalid read of size 4
==66525== at 0x1000148D5: Renderer::draw_triangle(Vec3<float>, Vec3<float>, Vec3<float>, Vec2<int>, Vec2<int>, Vec2<int>, Model, float) (in ./bin/main)
Sowie draw_triangle
ist genau die Methode, die Anrufe world_to_screen_space
und nutzt es aus.
Update 3: ich entdeckte die Quelle des Problems, und es war nicht alles, was im Zusammenhang mit diesem code — und es war etwas, was ziemlich offensichtlich, auch. Wirklich nicht sicher, was zu tun ist, über diese Frage jetzt.
Wenn es dennoch passiert (ohne debugger), ermöglichen Sie core-dumps, dann prüfen Sie den dump mit einem debugger.
Ich glaube nicht, verwenden Sie Zeiger auf alle in der code — nur Referenzen oder kopieren von Wert.
Das Problem ist wahrscheinlich in Ihrem
operator[]
UmsetzungKürzer, einfacher code ist auch leichter zu bekommen zu korrigieren.
InformationsquelleAutor Max Yankov | 2015-02-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ohne einen Prozessor, der überprüft, ob Versatz (wie @twalberg sagt), ist es unmöglich zu laufen und überprüfen Sie den code. Aber ich kann sagen: es ist ein allgemeiner Fehler in der C++ oder anderen Bibliotheken zu verwechseln eine Art von Ausnahme mit einem anderen Typ.
Meine Vermutung-sorry ich kann nicht mehr tun-ist, dass Sie erstellen Zuordnungen verloren gehen, mit Ihren verfügbaren Speicher, dann überläuft der Speicher. Die sehr seltene Ausnahme, die ausgelöst wird, wenn Sie größer sind als der verfügbare Speicher ist wahrscheinlich unerwartet und immer zurück, wie eine Verlagerung Fehler. Überprüfen Sie die Speichernutzung, wie Sie ausführen, um zu bestimmen, ob dies der Fall ist.
EDIT:
Meine Vermutung war falsch, und die valgrind-Ausgabe zeigt, dass die Falsch Adresse, die Fehler zu korrigieren. Laufen, dass war eine gute Idee. Der klare Hinweis darauf ist, dass es sich um einen Fehler auf einer niedrigeren Ebene als in Ihrem code, so dass meine ursprüngliche Idee ist sicherlich richtig: es gibt einen bug, dass es nicht in Ihrem code, aber maskiert ist.
Beachten Sie, dass es scheint, es ist ein Unterschied zwischen der Identität () - Konstruktor und der Matrix<,> Konstruktor, der ehemalige initialisiert wird entlang der diagonalen (langsam: besser wäre es, zu beseitigen, die innere Schleife) und die letztere nicht. Das könnte Einfluss auf das Verhalten der v2m-und m2v.
Ich weiß nicht; aber nicht alle code gezeigt wurde. Ich Editier meine Antwort bezieht sich jetzt auf die Eingabe von valgrind.
Ich habe das problem entdeckt, und es stellt sich heraus, dass es hatte nichts zu tun mit dem code, den ich gepostet und war wirklich nahe. Nach thisich sollte löschen Sie diese Frage, aber es gibt eine Menge tolle Diskussion hier. Nicht wirklich sicher, was zu tun; kann nicht akzeptieren, diese Antwort, weil es technisch nicht korrekt ist (es war nicht die Frage), obwohl Sie halfen mir sehr.
Ich kann nicht verpflichten Sie, aber bitte beachten Sie, dass der wie SE sollte in diesem Fall. Bitte Lesen. Man könnte noch darauf hinweisen, Sie Ihre Notizen in Ihre Antwort.
Vielen Dank für diese Diskussion, ich denke, ich werde tun, zu schreiben über dieses Thema später heute.
InformationsquelleAutor shipr