Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: minro editorial changes

...

In this compliant solution, the dynamically allocated memory is not deallocated until it is no longer required:.

Code Block
bgColor#ccccff
langcpp
#include <new>

struct S {
  void f();
};

void g() noexcept(false) {
  S *s = new S;
  // ...
  s->f();
  delete s;
}

...

When possible, use automatic storage duration instead of dynamic storage duration. Since s is not required to live beyond the scope of g(), this compliant solution uses automatic storage duration to limit the lifetime of s to the scope of g():.

Code Block
bgColor#ccccff
langcpp
struct S {
  void f();
};

void g() {
  S s;
  // ...
  s.f();
}

...

In the following noncompliant code example, the dynamically allocated memory managed by the buff object is accessed after it has been implicitly deallocated by the object's destructor:.

Code Block
bgColor#ffcccc
langcpp
#include <iostream>
#include <memory>
#include <cstring>
 
int main(int argc, const char *argv[]) {
  const char *s = "";
  if (argc > 1) {
    enum { BufferSize = 32 };
    try {
      std::unique_ptr<char[]> buff(new char[BufferSize]);
      std::memset(buff.get(), 0, BufferSize);
      // ...
      s = std::strncpy(buff.get(), argv[1], BufferSize - 1);
    } catch (std::bad_alloc &) {
      // Handle error
    }
  }

  std::cout << s << std::endl;
}

...

In this compliant solution, the lifetime of the buff object extends past the point at which the memory managed by the object is accessed:.

Code Block
bgColor#ccccff
langcpp
#include <iostream>
#include <memory>
#include <cstring>
 
int main(int argc, const char *argv[]) {
  std::unique_ptr<char[]> buff;
  const char *s = "";

  if (argc > 1) {
    enum { BufferSize = 32 };
    try {
      buff.reset(new char[BufferSize]);
      std::memset(buff.get(), 0, BufferSize);
      // ...
      s = std::strncpy(buff.get(), argv[1], BufferSize - 1);
    } catch (std::bad_alloc &) {
      // Handle error
    }
  }

  std::cout << s << std::endl;
}

...

In this compliant solution, a variable with automatic storage duration of type std::string is used in place of the std::unique_ptr<char[]>, which reduces the complexity and improves the security of the solution:.

Code Block
bgColor#ccccff
langcpp
#include <iostream>
#include <string>
 
int main(int argc, const char *argv[]) {
  std::string str;

  if (argc > 1) {
    str = argv[1];
  }

  std::cout << str << std::endl;
}

...

In this compliant solution, a local copy of the string returned by str_func() is made to ensure that string str will be valid when the call to display_string() is made:.

Code Block
bgColor#ccccff
langcpp
#include <string>
 
std::string str_func();
void display_string(const char *s);

void f() {
  std::string str = str_func();
  const char *cstr = str.c_str();
  display_string(cstr);  /* ok */
}

...

The compliant solution depends on programmer intent. If the programmer intends to allocate a single unsigned char object, the compliant solution is to use new instead of a direct call to operator new(), as this compliant solution demonstrates:.

Code Block
bgColor#ccccff
langcpp
void f() noexcept(false) {
  unsigned char *ptr = new unsigned char;
  *ptr = 0;
  // ...
  delete ptr;
}

...