test {0};
assert(test.size() == 1); // VECTOR HAS JUST ONE ELEMENT!
test.at(0) = 0; // SAFE
test.at(1) = 1; // CRASH!
test.at(9) = 9; // UNREACHABLE
return 0;
}
This time it crashes with a much more helpful error message:
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 1) >= this->size() (which is 1)
and if you back-trace in `gdb` it pinpoints exactly where the error is.
(Unlike with your initial error, when it actually crashes AFTER the
actual erroneous access.)
Due to the bounds-checking, you haven't overwritten any of the memory
management record-keeping, so it can give you honest results.
If you don't like bounds-checking, TOUGH... do it anyway. ONCE THE
PROGRAM IS WORKING, you can optimize it away where you really think you
need to. (Usually you don't.)
That's my $0.03.
CL
--=-=-=
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
1.0, user-scalable=3Dyes">
First thing I try to do is to reduce the program to the SMALLEST program=
that reproduces the same error. You can think of it as binary search: dele=
te (something like) HALF the program. If error is not reproduced, restore t=
hat half and delete the OTHER HALF. If error is reproduced, then delete hal=
f AGAIN. Continue until it=E2=80=99s as small as possible. Here=E2=80=99s t=
he minimal crashing program I came up with:
int main ( int argc, char *argv[] )
{
std::vector<int> test {0};
assert(test.size() =3D=3D 1); // VECTOR HAS JUST ONE ELEMENT!
for(int i =3D 0; i<10; i++ ){
test[i] =3D i; // THEREFORE THIS IS AN ERROR WHEN i>0
}
return 0;
}
It exhibits the same error yours does: =E2=80=9Cfree(): invalid next siz=
e (fast)=E2=80=9D. I added the assert
to test my assumption ab=
out what the {0}
initializer means.
I tried going even further by unrolling and =E2=80=98sampling=E2=80=99 t=
he loop:
int main ( int argc, char *argv[] )
{
std::vector<int> test {0};
assert(test.size() =3D=3D 1); // VECTOR HAS JUST ONE ELEMENT!
test[0] =3D 0; // SAFE
test[1] =3D 1; // ERR
test[9] =3D 9; // ERR
return 0;
}
But this =E2=80=93 unfortunately, IMO =E2=80=93 does not crash. Neverthe=
less, It=E2=80=99s still erroneous. It=E2=80=99s ABSOLUTELY NOT ALLOWED to =
read or write test[1]
or test[9]
because te=
st.size() =3D=3D 1
.
Anyway, the vector
type HAS a dereference operation that do=
es bounds-checking. You=E2=80=99ll be much better off if you USE IT. That w=
ould look like this:
int main ( int argc, char *argv[] )
{
std::vector<int> test {0};
assert(test.size() =3D=3D 1); // VECTOR HAS JUST ONE ELEMENT!
test.at(0) =3D 0; // SAFE
test.at(1) =3D 1; // CRASH!
test.at(9) =3D 9; // UNREACHABLE
return 0;
}
This time it crashes with a much more helpful error message:
terminate called after throwing an instance of 'std::out_of_=
range'
what(): vector::_M_range_check: __n (which is 1) >=3D this->size()=
(which is 1)
and if you back-trace in gdb
it pinpoints exactly where the=
error is. (Unlike with your initial error, when it actually crashes AFTER =
the actual erroneous access.)
Due to the bounds-checking, you haven=E2=80=99t overwritten any of the m=
emory management record-keeping, so it can give you honest results.
If you don=E2=80=99t like bounds-checking, TOUGH=E2=80=A6 do it anyway. =
ONCE THE PROGRAM IS WORKING, you can optimize it away where you really thin=
k you need to. (Usually you don=E2=80=99t.)
That=E2=80=99s my $0.03.
CL
--=-=-=--
--===============1668819183==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
Learn mailing list
Learn-at-nylxs.com
http://lists.mrbrklyn.com/mailman/listinfo/learn
--===============1668819183==--