ich eine Template-Klasse haben wie folgt definiert:C++ "neue T [Größe]" funktioniert nicht?
#include <stdio.h>
#include <queue>
using namespace std;
template<class T>
class tbufferpool {
private:
const int m_initial;
const int m_size;
const int m_total;
T *m_buffer;
vector<T*> m_queue;
public:
// constructor
tbufferpool(int initial, int size) : m_initial(initial), m_size(size), m_total(initial*size) {
m_buffer = new T[m_total];
T* next_buffer = m_buffer;
for (int i = 0; i < initial; ++i, next_buffer += size) {
m_queue.push_back(next_buffer);
}
}
und irgendwann im Konstruktor ich tun:
m_buffer = new T[size];
Dies funktioniert für die meisten Anwendungsfälle aber in einem Test habe ich den folgenden Speicher Fehler, der von Valgrind gemeldet wurde (Befehl und relevanter Ausschnitt unten), der Test ist jedoch noch in Ordnung. Das interessante Bit ist operator new(unsigned long)
was bedeutet, dass es nicht für die konkrete T-Typ-I-Setup "double" wie ich erwartet, sondern für unsigned long
Zuordnung und Ausrichtung? Wenn ich meine Pufferpool-Implementierung und hard-Code new double[size]
ändern, dann wird dieser Speicherfehler nicht angezeigt, aber natürlich arbeite ich nur mit tbufferpool<double>
jetzt.
Kann jemand Ratschläge wie man das beheben? die new T[size]
sollte legal sein? da die Template-Parameter zur Kompilierzeit vom Pre-Prozessor angewendet werden, der für jeden verwendeten Template-Typ eine neue Klasse erstellt. Wäre das ein Compilerfehler?
Die test_matrix ist eine Suite mit 30 Testfällen. Nur ein Test erzeugt das unten gezeigte Problem in Valgrind, dieser Test besteht trotzdem. Ich überprüfte alle Eingaben für den Funktionsaufruf, bei dem das Problem auftritt, unter Verwendung der new T[size]
Variante und druckte sie neben den gleichen Eingaben unter Verwendung der new double[size]
Variante. Ich vergleiche sie mit AraxisMerge und sie sind identisch. Ich fürchte, es ist ein Problem, das mit der Speicherausrichtung zusammen hängt, je nachdem, ob ich den Template-Parameter oder den konkreten Doppeltyp verwende ...?
$ valgrind --show-reachable=yes --dsymutil=yes --track-origins=yes ./test_matrix
[snip]
==3719== Conditional jump or move depends on uninitialised value(s)
==3719== at 0x3BE86C8: mkl_blas_dscal (in /opt/intel/composerxe-2011.4.184/mkl/lib/libmkl_mc3.dylib)
==3719== by 0x432FFFFFFFFFFFFF: ???
==3719== Uninitialised value was created by a heap allocation
==3719== at 0xD62F: malloc (vg_replace_malloc.c:266)
==3719== by 0x97B15C: operator new(unsigned long) (in /opt/local/lib/gcc46/libstdc++.6.dylib)
==3719== by 0x7FFF5FBFE54F: ???
==3719== by 0x10014BDBF: ???
==3719== by 0x7FFF5FBFE58F: ???
==3719== by 0x97B288: operator new[](unsigned long) (in /opt/local/lib/gcc46/libstdc++.6.dylib)
==3719== by 0x7FFF5FBFE58F: ???
==3719== by 0x100013853: tbufferpool<double>::tbufferpool(int, int) (bufferpool.h:30)
==3719== by 0x7003FFFFF: ???
==3719== by 0x100079E7F: ??? (in ./test_matrix)
==3719== by 0x7FFF5FBFE58F: ???
==3719== by 0x10014BE0F: ???
==3719==
==3719== Conditional jump or move depends on uninitialised value(s)
==3719== at 0x3BE86CA: mkl_blas_dscal (in /opt/intel/composerxe-2011.4.184/mkl/lib/libmkl_mc3.dylib)
==3719== by 0x432FFFFFFFFFFFFF: ???
==3719== Uninitialised value was created by a heap allocation
==3719== at 0xD62F: malloc (vg_replace_malloc.c:266)
==3719== by 0x97B15C: operator new(unsigned long) (in /opt/local/lib/gcc46/libstdc++.6.dylib)
==3719== by 0x7FFF5FBFE54F: ???
==3719== by 0x10014BDBF: ???
==3719== by 0x7FFF5FBFE58F: ???
==3719== by 0x97B288: operator new[](unsigned long) (in /opt/local/lib/gcc46/libstdc++.6.dylib)
==3719== by 0x7FFF5FBFE58F: ???
==3719== by 0x100013853: tbufferpool<double>::tbufferpool(int, int) (bufferpool.h:30)
==3719== by 0x7003FFFFF: ???
==3719== by 0x100079E7F: ??? (in ./test_matrix)
==3719== by 0x7FFF5FBFE58F: ???
==3719== by 0x10014BE0F: ???
[snip]
System:
/Users/bravegag/code/fastcode_project/build_debug$ uname -a && g++ --version
Darwin Macintosh-4.local 11.3.0 Darwin Kernel Version 11.3.0: Thu Jan 12 18:47:41 PST 2012;
root:xnu-1699.24.23~1/RELEASE_X86_64 x86_64
g++ (GCC) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Nur ein Gedanke, aber vielleicht liegt es daran, dass 'double' genauso groß ist wie' unsigned long'. – Tibor
Bitte versuchen Sie das Problem zu isolieren (eine Instantiierung der 'tbufferpool' Vorlage mit dem Typ double, entfernen Sie soviel wie möglich aus dem Konstruktor) und wiederholen Sie den Code. Am wichtigsten ist, wie 'Größe' initialisiert wird. –
Das bedeutet, dass Sie einen Teil des zugewiesenen Speichers nicht initialisiert haben, aber Sie sollten es getan haben. Initialisieren Sie diesen zugewiesenen Speicher? – mfontanini