C++: Respond to review comments.

This commit is contained in:
Mathias Vorreiter Pedersen
2023-09-13 11:43:12 +01:00
parent 81d20be1ee
commit af51a0a9ca
3 changed files with 22 additions and 18 deletions

View File

@@ -20,8 +20,10 @@ Use RAII ("Resource Acquisition Is Initialization") to manage the lifetime of ob
</recommendation>
<example>
<p>
The following two functions demonstrate common lifetime violations when working with the C++ standard library.
The following two examples demonstrate common lifetime violations when working with the C++ standard library.
</p>
<p>
The <code>bad_call_c_api</code> function contains a use of an expired lifetime.
First, a temporary object of type <code>std::string</code> is constructed, and a pointer to its internal buffer is stored in a local variable.
Once the <code>c_str()</code> call returns, the temporary object is destroyed, and the memory pointed to by <code>p</code> is freed.
@@ -31,6 +33,7 @@ The <code>good_call_c_api</code> function contains a fixed version of the first
The variable <code>hello</code> is declared as a local variable, and the pointer to its internal buffer is stored in <code>p</code>.
The lifetime of hello outlives the call to <code>c_api</code>, so the pointer stored in <code>p</code> remains valid throughout the call to <code>c_api</code>.
</p>
<sample src="UseAfterExpiredLifetime_c_api_call.cpp" />
<p>
The <code>bad_remove_even_numbers</code> function demonstrates a potential issue with iterator invalidation.
@@ -39,9 +42,8 @@ For example, calling <code>erase</code> on an object of type <code>std::vector&l
The <code>good_remove_even_numbers</code> function contains a fixd version of the third example.
The <code>erase</code> function returns an iterator to the element following the last element removed, and this return value is used to ensure that <code>it</code> remains valid after the call to <code>erase</code>.
</p>
<sample src="UseAfterExpiredLifetime.cpp" />
<sample src="UseAfterExpiredLifetime_iterator_invalidation.cpp" />
</example>
<references>
@@ -58,6 +60,9 @@ OWASP:
<li>
<a href="https://en.cppreference.com/w/cpp/container">Containers library</a>
</li>
<li>
<a href="https://en.cppreference.com/w/cpp/language/raii">RAII</a>
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,14 @@
void c_api(const char*);
void bad_call_c_api() {
// BAD: the memory returned by `c_str()` is freed when the temporary string is destroyed
const char* p = std::string("hello").c_str();
c_api(p);
}
void good_call_c_api() {
// GOOD: the "hello" string outlives the pointer returned by `c_str()`, so it's safe to pass it to `c_api()`
std::string hello("hello");
const char* p = hello.c_str();
c_api(p);
}

View File

@@ -1,18 +1,3 @@
void c_api(const char*);
void bad_call_c_api() {
// BAD: the memory returned by `c_str()` is freed when the temporary string is destroyed
const char* p = std::string("hello").c_str();
c_api(p);
}
void good_call_c_api() {
// GOOD: the "hello" string outlives the pointer returned by `c_str()`, so it's safe to pass it to `c_api()`
std::string hello("hello");
const char* p = hello.c_str();
c_api(p);
}
void bad_remove_even_numbers(std::vector<int>& v) {
// BAD: the iterator is invalidated after the call to `erase`.
for(std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {