Search code examples
c++iteratorconstantsinitializationconst-iterator

Valgrind says that const-iterator tries to access uninitialised space, but actually it is


I'm trying to use const_iterators to go through a list of elements (the elements of a matrix).

SparseMatrix matd(5,5,0); //5x5 matrix with 0 as default element.
//Follows elements insertion...
SparseMatrix<int>::const_iterator a,b;
a=matd.cbegin();
b=matd.cend();
while(a!=b){
    cout<<*(a->data)<<endl;
    ++a;
}

But there's something wrong, as valgrind reports.

==4662== Use of uninitialised value of size 8

==4662== at 0x403A19: SparseMatrix::findRow(int) const (SparseMatrix.h:120)

==4662== by 0x40431A: SparseMatrix::findNext(el const*) const (SparseMatrix.h:439)

==4662== by 0x4030B3: SparseMatrix::const_iterator::operator++() (SparseMatrix.h:593)

==4662== by 0x401D63: main (main.cpp:121)

==4662==

==4662== Invalid read of size 4

==4662== at 0x403A27: SparseMatrix::findRow(int) const (SparseMatrix.h:123)

==4662== by 0x40431A: SparseMatrix::findNext(el const*) const (SparseMatrix.h:439)

==4662== by 0x4030B3: SparseMatrix::const_iterator::operator++() (SparseMatrix.h:593)

==4662== by 0x401D63: main (main.cpp:121)

==4662== Address 0xa680020611a25ff is not stack'd, malloc'd or (recently) free'd

==4662==

==4662==

==4662== Process terminating with default action of signal 11 (SIGSEGV)

==4662== General Protection Fault

==4662== at 0x403A27: SparseMatrix::findRow(int) const (SparseMatrix.h:123)

==4662== by 0x40431A: SparseMatrix::findNext(el const*) const (SparseMatrix.h:439)

==4662== by 0x4030B3: SparseMatrix::const_iterator::operator++() (SparseMatrix.h:593)

==4662== by 0x401D63: main (main.cpp:121)

since I use findNext and findRow with normal iterators and other class methods, and they work, I think there's something wrong in operator++():

const_iterator& operator++() { const element *tmp=e; e=sm->findNext(tmp); delete tmp; return *this; }

const_iterator's copy constructor:

const_iterator(const const_iterator& it) { e=it.e; }

Moreover, const_iterators created and used inside a class' method work very well.

PS: The code of findRow

    mrow* findRow(int i) const {
    mrow *tmp = matrix;
    while(tmp!=NULL){
        if(tmp->idx == i) return tmp;
        tmp=tmp->next;
    }   
    return NULL;
}

It passes an if(tmp==NULL) check, so it thinks there's something there in memory, but then it says that it's uninitialized, but I'll say it again, if I use normal iterator it works.

Here's code for findNext

    element* findNext(const element* e) const {
    int r=e->i; 
    int c=e->j;
    int riga,colonna; 
    riga=r;
    while(riga!=-1){
            if(riga==r) {
                mrow *m=findRow(riga); 
                colonna=nextCol(m,c);
                if(colonna!=-1) {
                    T* d=&((findCol(findRow(riga),colonna)->data)); 
                    return genElement(riga,colonna,d);      
                }           
            }
            else{
                colonna=nextCol(findRow(riga),-1);
                if(colonna!=-1) {
                    T* d=&((findCol(findRow(riga),colonna)->data));
                    return genElement(riga,colonna,d);      
                }                       
            }
            riga=nextRow(riga);
    }
    return NULL;
}

Code for constructor SparseMatrix(int,int,T)

    SparseMatrix(int r, int c, T d){
    rows=r;
    cols=c;
    def=d;
    msize=0;
    matrix=NULL;
}

If you need more code just ask.

In addition let me confirm again that I use findRow and findNext for other purposes, and they work. I think that it's something related to constness, but can't get what.


Solution

  • This solved my problem: Use of uninitialised value of size 8

    It was an error in the code. In iterator assignment operator I forgot to initialize a fundamental value. This caused all the iterators, with the only exception of begin(), to read in the wrong place as their pointer to sparsematrix wasn't initialized.