使用返回"新节点"的函数出现问题而且我无法找到它。这是功能:
node* append_new_node(node* l, const T& tt) {
if (l == 0)
return new node(0, tt);
node* n = l;
while (n->next != 0) {
if (cmp(n->key, tt)) {
int a= n->counter;
a++;
n->counter=a;
n=0;
delete n;
return 0;
}
else {
n = n->next;
}
}
//check per evitare ripetizioni fra numeri uguali consecutivi
if (!cmp(n->key, tt)){
n->next = new node(0, tt);
}
else {
n->counter = n->counter+1;
n=0;
delete n;
return 0;
}
n=0;
delete n;
return l;
}
valgrind报告:
==2481== HEAP SUMMARY:
==2481== in use at exit: 480 bytes in 16 blocks
==2481== total heap usage: 81 allocs, 65 frees, 2,440 bytes allocated
==2481==
==2481== Searching for pointers to 16 not-freed blocks
==2481== Checked 193,240 bytes
==2481==
==2481== 96 (32 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record 6 of 10
==2481== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2481== by 0x404039: huffman<Color, CaseInsensitiveCmp>::append_new_node(huffman<Color, CaseInsensitiveCmp>::node*, Color const&) (huffman.h:311)
==2481== by 0x402D61: huffman<Color, CaseInsensitiveCmp>::node* huffman<Color, CaseInsensitiveCmp>::build_list<std::_List_iterator<Color> >(std::_List_iterator<Color>, std::_List_iterator<Color>, unsigned int&) (huffman.h:344)
==2481== by 0x402283: huffman<Color, CaseInsensitiveCmp>::huffman<std::_List_iterator<Color> >(std::_List_iterator<Color>, std::_List_iterator<Color>) (huffman.h:103)
==2481== by 0x4016F5: do_test() (main.cpp:137)
==2481== by 0x401BCB: main (main.cpp:192)
==2481==
==2481== 96 (32 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record 7 of 10
==2481== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2481== by 0x404039: huffman<Color, CaseInsensitiveCmp>::append_new_node(huffman<Color, CaseInsensitiveCmp>::node*, Color const&) (huffman.h:311)
==2481== by 0x402D61: huffman<Color, CaseInsensitiveCmp>::node* huffman<Color, CaseInsensitiveCmp>::build_list<std::_List_iterator<Color> >(std::_List_iterator<Color>, std::_List_iterator<Color>, unsigned int&) (huffman.h:344)
==2481== by 0x402389: void huffman<Color, CaseInsensitiveCmp>::reset<std::_List_iterator<Color> >(std::_List_iterator<Color>, std::_List_iterator<Color>) (huffman.h:112)
==2481== by 0x40186F: do_test() (main.cpp:151)
==2481== by 0x401BCB: main (main.cpp:192)
==2481==
==2481== 96 (32 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record 8 of 10
==2481== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2481== by 0x404039: huffman<Color, CaseInsensitiveCmp>::append_new_node(huffman<Color, CaseInsensitiveCmp>::node*, Color const&) (huffman.h:311)
==2481== by 0x403363: huffman<Color, CaseInsensitiveCmp>::node* huffman<Color, CaseInsensitiveCmp>::build_list<huffman<Color, CaseInsensitiveCmp>::const_iterator>(huffman<Color, CaseInsensitiveCmp>::const_iterator, huffman<Color, CaseInsensitiveCmp>::const_iterator, unsigned int&) (huffman.h:344)
==2481== by 0x4023F4: huffman<Color, CaseInsensitiveCmp>::huffman(huffman<Color, CaseInsensitiveCmp> const&) (huffman.h:86)
==2481== by 0x401936: do_test() (main.cpp:159)
==2481== by 0x401BCB: main (main.cpp:192)
==2481==
==2481== 96 (32 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record 9 of 10
==2481== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2481== by 0x404039: huffman<Color, CaseInsensitiveCmp>::append_new_node(huffman<Color, CaseInsensitiveCmp>::node*, Color const&) (huffman.h:311)
==2481== by 0x403363: huffman<Color, CaseInsensitiveCmp>::node* huffman<Color, CaseInsensitiveCmp>::build_list<huffman<Color, CaseInsensitiveCmp>::const_iterator>(huffman<Color, CaseInsensitiveCmp>::const_iterator, huffman<Color, CaseInsensitiveCmp>::const_iterator, unsigned int&) (huffman.h:344)
==2481== by 0x4023F4: huffman<Color, CaseInsensitiveCmp>::huffman(huffman<Color, CaseInsensitiveCmp> const&) (huffman.h:86)
==2481== by 0x4024B7: huffman<Color, CaseInsensitiveCmp>::operator=(huffman<Color, CaseInsensitiveCmp> const&) (huffman.h:135)
==2481== by 0x401AEC: do_test() (main.cpp:183)
==2481== by 0x401BCB: main (main.cpp:192)
==2481==
==2481== 96 (24 direct, 72 indirect) bytes in 1 blocks are definitely lost in loss record 10 of 10
==2481== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2481== by 0x40398D: huffman<int, IntCmp>::append_new_node(huffman<int, IntCmp>::node*, int const&) (huffman.h:311)
==2481== by 0x402687: huffman<int, IntCmp>::node* huffman<int, IntCmp>::build_list<std::_List_iterator<int> >(std::_List_iterator<int>, std::_List_iterator<int>, unsigned int&) (huffman.h:344)
==2481== by 0x402021: huffman<int, IntCmp>::huffman<std::_List_iterator<int> >(std::_List_iterator<int>, std::_List_iterator<int>) (huffman.h:103)
==2481== by 0x40151A: dotest_iterators() (main.cpp:113)
==2481== by 0x401BD0: main (main.cpp:193)
==2481==
==2481== LEAK SUMMARY:
==2481== definitely lost: 152 bytes in 5 blocks
==2481== indirectly lost: 328 bytes in 11 blocks
==2481== possibly lost: 0 bytes in 0 blocks
==2481== still reachable: 0 bytes in 0 blocks
==2481== suppressed: 0 bytes in 0 blocks
==2481==
==2481== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
==2481== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
samu@Samu-MS-7821:~/Desktop/test$
我现在还要复制valgrind命名的其他类
template <typename InIter>
node* build_list(InIter from, InIter to, unsigned int& sz){
unsigned int n = 0;
node* h = 0;
while (from != to) {
node* tmp;
try {
tmp = append_new_node(h, *from);
} catch(...) {
free_nodes(h);
throw;
}
if (tmp != 0) {
++n;
h = tmp;
}
++from;
tmp=0;
delete tmp;
}
sz = n;
//creo un array di frequenze
int frequenze[sz];
node* scor=h;
int i=0;
while(scor!=0){
int prova=scor->counter;
frequenze[i]=prova;
i++;
scor=scor->next;
}
//ordino array
insertion_sort(frequenze,sz);
//creo lista ordinata+assegno codifica
node* coded = 0;
string endcode="1";
string midcode="\n";
string code;
for(int q=sz-1;q>=0;q--){
node* temp;
code=(midcode+endcode);
try {
temp = append_new_node_c(coded, find_freq(h,frequenze[q]), code);
//std::cout<<frequenze[q]<<"\n";
} catch(...) {
free_nodes(h);
throw;
}
coded=temp;
if(q-1<=0){
endcode="0";
}
else{
midcode=midcode+"0";
}
}
h=0;
scor=0;
delete h;
delete scor;
return coded;}
另一个功能
huffman(const huffman& v)
: head(0), sz(0), cmp(v.cmp){
head = build_list(v.begin(), v.end(), sz);}
真的,如果有人可以帮助我,那真是棒极了。我真的找不到我必须释放或删除,以防止此内存泄漏。 我不复制所有的代码原因是大约300行,但如果你需要它我会。
这是主要的
int main(){
try {
do_test();
dotest_iterators();
std::cout << "ok\n";}
catch (std::exception& e){
std::cerr << e.what() << std::endl;}
return 0;}
class Color{
public:
Color(int r, int g, int b): red(r), green(g), blue(b){}
void print(std::ostream& os) const{
os << "Color("
<< red << ", "
<< green << ", "
<< blue << ")";}
bool operator==(const Color& c) const {
return red == c.red && green == c.green && blue == c.blue;}
bool operator!=(const Color& c) const {
return !operator==(c);
}
private:
int red;
int green;
int blue;
};
/* Stampa un'istanza di Color. */
std::ostream& operator<<(std::ostream& os,
const Color& c){
c.print(os);
return os;}
struct CaseInsensitiveCmp{
bool operator()(const Color& a, const Color& b) const{
return a==b;}
};
struct IntCmp{
bool operator()(const int& a, const int& b) const{
return a==b;
}
};
void dotest_iterators(){
typedef IntCmp IntCompare;
std::list<int> lista;
int a,b,c,d,e,f,g,h;
a=1;
b=2;
c=2;
d=1;
e=1;
f=7;
g=1;
h=6;
lista.push_front(a);
lista.push_front(b);
lista.push_front(c);
lista.push_front(d);
lista.push_front(e);
lista.push_front(f);
lista.push_front(g);
lista.push_front(h);
//test sul codice
//std::equal_to<int>
huffman<int, IntCompare > codHuff(lista.begin(),lista.end());
//std::cout << codHuff.size() << "\n";
assert(codHuff.size()==4);
//test valori di codifica
codHuff.find(1);
codHuff.find(2);
codHuff.find(6);
codHuff.find(7);}
void do_test(){
typedef CaseInsensitiveCmp ColorCompare;
std::list<Color> lista2;
//creazione lista e test funzione stampa e size
lista2.push_front(Color(255, 0, 0));
lista2.push_front(Color(0, 255, 0));
lista2.push_front(Color(0, 0, 255));
lista2.push_front(Color(255, 0, 0));
huffman<Color, ColorCompare > codHuff2(lista2.begin(),lista2.end());
assert(codHuff2.size()==3);
codHuff2.find(Color(255, 0, 0));
codHuff2.find(Color(0, 255, 0));
codHuff2.find(Color(0, 0, 255));
std::list<Color> lista3;
lista3.push_front(Color(0, 255, 0));
lista3.push_front(Color(0, 0, 255));
lista3.push_front(Color(255, 0, 0));
//funzione reset
codHuff2.reset(lista3.begin(),lista3.end());
assert(codHuff2.size()==3);
codHuff2.find(Color(255, 0, 0));
codHuff2.find(Color(0, 255, 0));
codHuff2.find(Color(0, 0, 255));
//copy constructor
huffman<Color, ColorCompare > codHuff3(codHuff2);
assert(codHuff2.size() == codHuff3.size());
codHuff3.find(Color(255, 0, 0));
codHuff3.find(Color(0, 255, 0));
codHuff3.find(Color(0, 0, 255));
try {
codHuff2.find(Color(0, 3, 255));
assert(0);
} catch(element_not_found&) {
}
//clear
codHuff3.clear();
assert(codHuff3.size()==0);
//swap
codHuff2.swap(codHuff3);
assert(codHuff2.size()==0);
assert(codHuff3.size()==3);
//assegnamento
codHuff2=codHuff3;
assert(codHuff2.size()==3);}
我希望你们能帮助我
更新:我将所有代码放在这里:
#ifndef fuffman_h
#include <stdexcept>
#include <iterator>
#include <cassert>
#include <string>
#include <iostream>
#include <exception>
using namespace std;
/** Versione 2: introduzione degli iteratori. */
/**
* Eccezione lanciata quando si cerca di inserire una chiave gia'
* presente.
*/
struct duplicated_element : std::runtime_error
{
duplicated_element() : std::runtime_error("Duplicated Element") { }
};
/**
* Eccezione lanciata quando nussuna delle coppie memorizzate
* corrisponde alla chiave rischiesta.
*/
struct element_not_found : std::runtime_error
{
element_not_found() : std::runtime_error("Element not found") { }
};
/**
* Struttura contenente le coppie chiave/valore. NON NECESSARIA?
*/
/*
template <typename K, typename T>
struct key_value_pair
{
key_value_pair(const K& kk, const T& vv) : key(kk), value(vv) { }
template <typename K1, typename T1>
key_value_pair(const key_value_pair<K1, T1>& p) : key(p.key), value(p.value) { }
K key;
T value;
};
*/
/**
* Un vettore associativo.
*
* Contiene coppie chiave/valore di tipo K e T, rispettivamente. Non
* e' possibile inserire piu' coppie con chiave equivalenti.
* L'equivalenza tra le chiavi e' definita tramite un funtore
* specificato dall'utente.
*/
template <typename T, typename Cmp>
class huffman
{
public:
// typedef key_value_pair<K, T> pair;
/**
* Costruttore di default.
*
* Il vettore associativo risultante e' vuoto.
*/
huffman() : head(0), sz(0), cmp() { }
explicit huffman(const Cmp& c) : head(0), sz(0), cmp(c) { }
/**
* Copy constructor.
*
* In questa versione l'ordine interno delle copie memorizzate
* risulta invertito.
*/
huffman(const huffman& v)
: head(0), sz(0), cmp(v.cmp)
{
head = build_list(v.begin(), v.end(), sz);
}
template<typename T1, typename Cmp1>
huffman(const huffman<T1, Cmp1>& v)
: head(0), sz(0), cmp()
{
head = build_list(v.begin(), v.end(), sz);
}
//La funzione prende in ingresso due iteratori puntanti a inizio e fine di una lista e ne creano l'array
template <typename InIter>
huffman(InIter from, InIter to)
: head(0), sz(0), cmp()
{
head = build_list(from, to, sz);
}
template <typename InIter>
void reset(InIter from, InIter to)
//: head(0), sz(0), cmp()
{
if(head!=0){
clear();}
head = build_list(from, to, sz);
}
template <typename InIter>
huffman(InIter from, InIter to, const Cmp& c)
: head(0), sz(0), cmp(c)
{
head = build_list(from, to, sz);
}
/**
* Distruttore.
*/
~huffman()
{
free_nodes(head);
}
/**
* Operatore di assegnamento.
*/
huffman& operator=(const huffman& v)
{
huffman tmp(v);
swap(tmp);
return *this;
}
template<typename T1, typename Cmp1>
huffman& operator=(const huffman<T1, Cmp1>& v)
{
huffman tmp(v);
swap(tmp);
return *this;
}
//???
/*
template <typename InIter>
void assign(InIter from, InIter to)
{
huffman tmp(from, to);
swap(tmp);
}
*/
/**
* Inserisce una nuova coppia nel vettore.
*
* Lancia l'eccezione duplicated_element Nel caso in cui la chiave sia
* gia' presente.
*/
//E' UTILE AI FINI DEL PROGETTO? ELEIMINARE O SPOSTARE IN PRIVATE?
//PER ORA LA TOLGO
/*
void insert(const T& t)
{
node* r = append_new_node(head, t);
if (r == 0)
throw duplicated_element();
head = r;
++sz;
}
*/
/**
*Stampa codifica, dato un elemento.
*
* Lancia l'eccezione element_not_found se nessun elemento corrisponde
* alla chiave specificata.
*/
void find(const T& t)
{
node* n = find_code(head, t);
if (n == 0)
throw element_not_found();
n=0;
delete n;
}
/**
* Rimuove la coppia corrispondente alla chiave specificata.
*
* Lancia l'eccezione element_not_found se nessun elemento corrisponde
* alla chiave specificata.
*/
//E' UTILE AI FINI DEL PROGETTO? ELIMINARE O SPOSTARE IN PRIVATE???
//PER ORA LA TOLGO
/*
void erase(const T& t)
{
node* n = find_node(head, t);
if (n == 0)
throw element_not_found();
--sz;
head = erase_node(head, n);
}
*/
/**
* Restituisce il numero di coppie memorizzate.
*/
unsigned int size() const
{
return sz;
}
/**
* Svuota il vettore associativo.
*/
void clear()
{
huffman tmp;
swap(tmp);
}
/**
* Scambia il contenuto di due vettori associativi.
*/
void swap(huffman& v) {
node* tmp = head; head = v.head; v.head = tmp;
unsigned int tmps = sz;
sz = v.sz;
v.sz = tmps;
Cmp tmpc = cmp;
cmp = v.cmp;
v.cmp = tmpc;
}
private:
// L'implementazione si basa su una lista a link singolo.
struct node {
node(node* n, const T& tt) : key(tt), counter(1), codifica(""), next(n){ }
node(node* n, const T& tt, string c) : key(tt), counter(0), codifica(c), next(n){ }
T key;
int counter;
string codifica;
node* next;
};
node* head; // Puntatore alla testa della lista
unsigned int sz; // Numero di coppie memorizzate
Cmp cmp; // funtore di confronto tra chiavi
// Inserisce p in testa alla lista l. Restituisce il nuovo nodo. MI SERVE?
node* insert_node(node* l, const T& tt)
{
node* ret = new node(l, tt);
return ret;
}
//Appendo con codifica
node* append_new_node_c(node* l, const T& tt, string c)
{
if (l == 0)
return new node(0, tt, c);
node* n = l;
while (n->next != 0) {
if (cmp(n->key, tt)) {
int a= n->counter;
a++;
n->counter=a;
n=0;
delete n;
return 0;}
else{
n = n->next;
}
}
//check per evitare ripetizioni fra numeri uguali consecutivi
if (!cmp(n->key, tt)){
n->next = new node(0, tt, c);}
else{
n->counter=n->counter+1;
n=0;
delete n;
return 0;}
n=0;
delete n;
return l;
}
// Append
node* append_new_node(node* l, const T& tt)
{
if (l == 0)
return new node(0, tt);
node* n = l;
while (n->next != 0) {
if (cmp(n->key, tt)) {
int a= n->counter;
a++;
n->counter=a;
n=0;
delete n;
return 0;}
else{
n = n->next;
}
}
//check per evitare ripetizioni fra numeri uguali consecutivi
if (!cmp(n->key, tt)){
n->next = new node(0, tt);}
else{
n->counter=n->counter+1;
n=0;
delete n;
return 0;}
n=0;
delete n;
return l;
}
//implementa qua merge e codifica
template <typename InIter>
node* build_list(InIter from, InIter to, unsigned int& sz)
{
unsigned int n = 0;
node* h = 0;
while (from != to) {
node* tmp;
try {
tmp = append_new_node(h, *from);
} catch(...) {
free_nodes(h);
throw;
}
if (tmp != 0) {
++n;
h = tmp;
}
++from;
tmp=0;
delete tmp;
}
sz = n;
//creo un array di frequenze
int frequenze[sz];
node* scor=h;
int i=0;
while(scor!=0){
int prova=scor->counter;
frequenze[i]=prova;
i++;
scor=scor->next;
}
//ordino array
insertion_sort(frequenze,sz);
//creo lista ordinata+assegno codifica
node* coded = 0;
string endcode="1";
string midcode="\n";
string code;
for(int q=sz-1;q>=0;q--){
node* temp;
code=(midcode+endcode);
try {
temp = append_new_node_c(coded, find_freq(h,frequenze[q]), code);
//std::cout<<frequenze[q]<<"\n";
} catch(...) {
free_nodes(coded);
throw;
}
coded=temp;
temp=0;
delete temp;
if(q-1<=0){
endcode="0";
}
else{
midcode=midcode+"0";
}
}
h=0;
scor=0;
delete h;
delete scor;
return coded;
}
//trovo i T dalle frequenze
T find_freq(node* l, const int f)
{
while (l != 0) {
if (l->counter==f){
//resetto il counter affinchè non venga ricercato in seguito
l->counter=0;
return l->key;}
l = l->next;
}
//return 0;
}
const T find_freq(const node* l, const int f) const
{
while (l != 0) {
if (l->counter==f){
l->counter=0;
return l->key;}
l = l->next;
}
//return 0; //SERIO PROBLEMA AL RIGUARDO DI CIO PER LE CLASSI/COSTRUTTI che a quanto pare viene risolto restituendo un fico secco
}
//STAMPA DELLA CODIFICA
node* find_code(node* l, const T& t)
{
while (l != 0) {
if (cmp(l->key, t)){
std::cout << l->codifica<<" codifica \n";
return l;}
l = l->next;
}
return 0;
}
const node* find_code(const node* l, const T& t) const
{
while (l != 0) {
if (cmp(l->key, t)){
std::cout << l.codifica;
return l;}
l = l->next;
}
return 0;
}
// Cerca k nella lista l. Restituisce il nodo corrispondente, o null
// se la chiave non viene trovata.
node* find_node(node* l, const T& t)
{
while (l != 0) {
if (cmp(l->key, t))
return l;
l = l->next;
}
return 0;
}
const node* find_node(const node* l, const T& t) const
{
while (l != 0) {
if (cmp(l->key, t))
return l;
l = l->next;
}
return 0;
}
/// Toglie n da l
node* erase_node(node* l, node* n)
{
node* h = l;
if (l == n) {
l = l->next;
delete n;
return l;
}
while (l != 0 && l->next != n) {
l = l->next;
}
if (l == 0)
return h;
l->next = n->next;
delete n;
return h;
}
void free_nodes(node* l)
{
while (l != 0) {
node* tmp = l;
l = l->next;
delete tmp;
}
}
void insertion_sort(int arr[], int length) {
int i, j ,tmp;
for (i = 1; i < length; i++) {
j = i;
while (j > 0 && arr[j - 1] > arr[j]) {
tmp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = tmp;
j--;
}
}
}
public:
class iterator
{
public:
typedef T value_type;
typedef int distance_type;
typedef T* pointer;
typedef T& reference;
typedef std::forward_iterator_tag iterator_category;
iterator() : n(0) {}
// iterator(const iterator& it);
// iterator& operator=(const iterator& it);
iterator& operator++()
{
assert(n != 0);
n = n->next;
return *this;
}
iterator operator++(int)
{
iterator tmp = *this;
operator++();
return tmp;
}
reference operator*() const
{
assert(n != 0);
return n->key;
}
pointer operator->() const
{
assert(n != 0);
return &(n->key);
}
private:
explicit iterator(node* nn) : n(nn) { }
node* n;
friend class huffman;
friend bool operator==(const iterator& a, const iterator& b)
{
return a.n == b.n;
}
friend bool operator!=(const iterator& a, const iterator& b)
{
return !(a == b);
}
};
class const_iterator
{
public:
typedef const T value_type;
typedef int distance_type;
typedef const T* pointer;
typedef const T& reference;
typedef std::forward_iterator_tag iterator_category;
const_iterator() : n(0) {}
const_iterator(const iterator& it) : n (it.n) { }
const_iterator& operator=(const iterator& it)
{
n = it.n;
return *this;
}
const_iterator& operator++()
{
assert(n != 0);
n = n->next;
return *this;
}
const_iterator operator++(int)
{
const_iterator tmp = *this;
operator++();
return tmp;
}
reference operator*() const
{
assert(n != 0);
return n->key;
}
pointer operator->() const
{
assert(n != 0);
return &(n->key);
}
private:
explicit const_iterator(node* nn) : n(nn) { }
const node* n;
friend class huffman;
friend bool operator==(const const_iterator& a, const const_iterator& b)
{
return a.n == b.n;
}
friend bool operator!=(const const_iterator& a, const const_iterator& b)
{
return !(a == b);
}
};
iterator begin() { return iterator(head); }
iterator end() { return iterator(0); }
const_iterator begin() const { return const_iterator(head); }
const_iterator end() const { return const_iterator(0); }
iterator finditer(const T& t)
{
return iterator(find_node(head, t));
}
const_iterator finditer(const T& t) const
{
return const_iterator(find_node(head, t));
}
};
#endif
答案 0 :(得分:1)
您在>>释放指针之前将其归零:
n = 0;
delete n;
如果您将空指针传递给delete
,它将忽略它,并且调用会产生一个nop。
正确的操作顺序是:
delete n; // Free referenced data
n = 0; // Erase the reference