some guesses (not checked with your code!!)
There are two values for the number of nonzeros in ublas
m.nnz() and m.nnz_capacity().
1. m.nnz_capacity() gives you the size of the array m.value_data().
2. m.nnz() gives you the size of the actually used number of nonzeros.
compressed_matrix<double> m (4, 4); creates a 4 by 4 matrix with
a capacity of m.nnz_capacity() == 0; Then you insert some
elements. Which means, ublas has to realloce m.value_data().
Now, ublas strategy is not to reallocate for every insertion
an array with a capacity of one more then the previous m.nnz_capacity().
This would lead to a lot of reallocations. I don't know exactly but maybe
ublas doubles always the capacity of the m.value_data() array if during
insertion the previous capacity limit is reached.
If it doubles the capacity every time you reach the limit of the previous
capacity, then the insertion of the 5th element in your example
should already lead to a size() == 8 of m.value_data().
I never checked this, but there is something like
if (filled2_ >= capacity_)
reserve (2 * filled2_, true);
If you know yor number of nonzeros in advance you could do
(in your example code) compressed_matrix<double> m (4, 4, 6);
and then there should be no need for ublas to increase the size
of the array m.value_data().
Sorry, for not checking my guesses