Resource allocation is initialization

from Wikipedia, the free encyclopedia

Resource allocation is initialization, usually abbreviated to RAII, for English resource acquisition is initialization , denotes a programming technique for managing resources (also called resources ) that is widespread in certain programming languages ​​(such as C ++ ). The allocation of resources to the constructor call of a variable of a user-defined type and the release of the resources to its destructor callbound. The automatic release is triggered, for example, by leaving the validity range (at the end of the block, when an exception is triggered, by returning it to the caller, etc.), the implicit destructor call of the variable then ensures that the resource is released again.

application

Typical applications for RAII are the control of process or thread locks in concurrent programs and the management of file operations. Since destructors are called automatically even under exceptional conditions, RAII is also a key concept for writing exception-resistant code.

The programming languages ​​that enable the use of the RAII programming technique include, for example, C ++ , Ada , D and Rust . In C # or Java , on the other hand, this technology is not directly possible, since there the destruction of all objects is managed by a concurrent garbage collector (see section Variants ).

example

The following sample program is written in the C ++ programming language:

#include <string>
#include <cstdio>

class Datei {
    FILE* datei_;

public:
    Datei(const std::string& name)
    : datei_( std::fopen(name.c_str(), "w+") ) {} // Öffnen der Datei

    ~Datei() {
         std::fclose(datei_); // Schließen der Datei
    }

    void ausgeben(const std::string& text) {
        if (datei_)
            std::fputs(text.c_str(), datei_);
    }
};

int main() {
    Datei datei("aufzeichnung.txt"); // Öffnen der Datei (Anfordern der Ressource)
    datei.ausgeben("Hallo Welt!");

    // Mit dem Ende der Funktion endet auch der Gültigkeitsbereich (Scope)
    // des Objekts datei. Daher wird der Destruktor Datei::~Datei()
    // aufgerufen, der die Datei schließt → Freigabe der Ressource.
}

Second example

not RAII:

void func(void)
{
    char* buffer = new char[3];
    buffer[0] = 'A';
    buffer[1] = 'B';
    buffer[2] = 'C';

    // buffer verwenden

    delete[] buffer;
}

RAII:

void func(void)
{
    std::vector<char> buffer = {'A', 'B', 'C'};

    // buffer verwenden   
}

variants

The correct functioning of this technique depends largely on the properties of the constructors and destructors of the language. In C ++, the language standard guarantees that an object is created when it is passed through its declaration and that its constructor is called in the process. If the object is out of scope, it must be destroyed; H. its destructor is called and can cause resources to be released. However, in no programming language can it be guaranteed that a destructor will be called, since programs can always be terminated abnormally (e.g. by a power failure or SIGKILL ). In such cases, however, no programming technology can ensure the correct release of resources.

Programming languages ​​with garbage collection , such as B. C # or Java make no guarantees about the point in time at which a no longer referenced object will be reclaimed by the garbage collector. This point in time at which an object is destroyed and the finalization method is called is no longer deterministic in the case of concurrent garbage collection . As a result, the object can occupy a resource longer than expected, especially beyond its area of ​​validity. In general, this problem can only be avoided by explicitly calling a function for releasing the resources and / or using special language constructs.

The alternative recommended for C # is to implement the System.IDisposableinterface - also known as the Dispose Pattern . Using the using-Block ensures that the method is called Dispose()at the end of this block in order to release occupied resources at a defined point in time.

In Java, the try-with-resources statement can be used in a similar way to ensure that resources are released in reverse order at the end of a scope.

Web links

Individual evidence

  1. B. Strousroup: The C ++ - programming , p 259F, p 390 f, 4th Edition, Addison-Wesley. ISBN 978-3-827-31756-8
  2. Nagel, Elvin, et al .: C # 2012 and .NET 4.5 , pp. 353 ff., John Wiley & Sons, 2013, ISBN 978-1-118-31442-5
  3. ^ A. Jones, et al .: Visual C # 2010 Recipes: A Problem-Solution Approach , pp. 647 ff., 2010, Apress
  4. F. Eller: Visual C sharp 2010 , pp. 200 f., 2010, Pearson Germany
  5. Oracle Java Tutorial: The try-with-resources Statement
  6. Java Language Specification: Chapter 14, Blocks and Statements, try-with-resources