문제

I've been teaching myself C++ and someone told me that C++ does not have a garbage collector. Now I'm not sure to what extent this means.

Lets say I have this code :

double multiply (double a, double b) {
    double result = a * b;
    return result;
};
int main (char* args[]) {
    double num1 = 3;
    double num2 = 12;
    double result = multiply(num1, num2);
    return 0;
}

The multiply method contains an internal variable "result". Now is the memory address for the variable "result" still allocated and/or locked? And how about the parameters "a" & "b"?

도움이 되었습니까?

해결책

Standard C++ doesn't have a garbage collector at all.

But automatic variables ("stack" variables) are cleaned up when their scope ends, calling destructors if/when necessary. (All the variables in your example are automatic.)

What you have to worry about is dynamic allocations: anything you create via the new operator. Those are not cleaned up automatically - you need to delete them or they will leak. (Or use smart pointers.)

다른 팁

All the variables you mentioned are on the stack. Once they go out of the scope, the memory is released automatically.

Garbage collection means that your garbage (not accessible/referenced memory on the heap) will be freed automatically. Local memory/variables (local variables) won't get allocated but pushed onto the stack and freed automatically if you leave the block where you defined the var.

So if you use your code you're fine. But if you use

double multiply (double a, double b) {
    double *result = new double;
    *result = a * b;
    return *result;
};

then the memory in result is still allocated, 'locked' and lost. See also http://en.wikipedia.org/wiki/Call_stack and http://en.wikipedia.org/wiki/Dynamic_memory_allocation#Dynamic_memory_allocation.

Actually, C++ is very good a resource management! It doesn't do garbage collection for object allocated on the heap. You, reasonably, didn't allocate anything on the heap and in many cases when you do it you probably don't do it explicitly (e.g. when using std::vector<T>). To get resource leaks which is dealt with by garbage collection in other languages are objects allocate on the heap using new: you need to pair every memory allocation (well, any resource allocation, really) with a a corresponding release. Using things like std::vector<T> and std::shared_ptr<T> is dealing with the vast amount of resource leaks in C++.

That is, you example program has no resource leaks.

C++ has two main types of memory where objects are allocated: the stack and the free store (heap). Objects on the stack are allocated and deallocated manually and these include function parameters, automatic (local) variables, temporary objects, return values. Objects on the free store (heap) are instead managed explictly with new, new[], delete and delete[]. You can also manage raw memory from the free store using malloc/free or using fancy named functions operator new and operator delete and their [] counterparts.

For objects managed on the free store in C++ it's a programmer's responsibility to take care of allocations and deallocations... in other languages this is instead automatic. In C++ also you need to pay attention that lifetime of stack-based objects is bound to the scope (and for example storing or returning the address of a local variable is a common error, orinig of many bugs) while this is also a non problem in other languages.

The main reason for this complication is speed: using a stack based allocation logic is way faster than using a free store (with current processors allocating many variables on the stack simply requires one addition, and deallocating them just a subtraction).

With other languages the compiler analyzes the code and decides where stack allocation can be used and where it cannot, this instead in C++ is a job for the programmer.

Note that in C++ memory management is actually a bit more convoluted than this explanation (for example there is also the memory where exception objects are stored, there can be custom allocators for classes and there is the allocator parameter for containers) but a programmer rarely needs to consider it.

It is (mostly, ignoring external libraries) true that C++ does not have a garbage collector. Instead, it has the concept of automatic storage duration.

Objects within a scope have a lifetime which is delimited by that scope, in your example, result is constructed within multiply, and then a copy of result is returned to main, where it is again copied into the result in main.

At the end of the scope of multiply, result is destroyed, and the memory which holds it result is freed.

This "automatic memory management" does not use a garbage collector, and it is entirely deterministic.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top