0

I asked my friend if he can print from 1 to 1000 without using loops or coditionals after being intrigued by this thread:

Printing 1 to 1000 without loop or conditionals

He replied with this program.

#include <iostream>
using namespace std;

static int n = 1;

class f {
public:

    f() {
        cout << n++ << endl;
    }
};

int main(int argc, char *argv[]) {
    f n [1000];
}

Running the program outputs ok. But when I close the program on netbeans it seems to be still running and consuming memory. Is the program causing memory leak? And can someone explain how this small program works?

Community
  • 1
  • 1
  • The very term "memory leak" has meaning only for a program which loops (and potentially allocates memory on each iteration), and runs potentially unbounded time. – Vlad Jul 05 '12 at 11:21
  • Thanks everyone for explaining. I learned some basic things pretty fast. Stackoverflow is good :) –  Jul 05 '12 at 11:41
  • It is ambiguous naming if the class "f" that makes this code snippet a bit puzzling. If you name it "class Array", the line Array n[1000]; looks more understandable. – SChepurin Jul 05 '12 at 12:33

5 Answers5

9

But when I close the program on netbeans it seems to be still running and consuming memory

When you close a program or it terminates, regardless of whether or not it has memory leaks, the memory will be released. I'm pretty sure you're not terminating it correctly.

Is the program causing memory leak?

No, you can't have a memory leak if you don't use new or malloc (either directly or indirectly)

And can someone explain how this small program works?

f n [1000]; attempts to create a vector of 1000 f objects. When they get initialized, the constructor is called, printing n and incrementing it.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Strictly speaking, one never knows if `ostream::operator<<(int)` allocates memory under the hood. – Vlad Jul 05 '12 at 11:22
  • @Vlad I'm pretty sure any implementation that has a leak in `ostream::operator<<(int)` would meet its end the very next day it's released. – Luchian Grigore Jul 05 '12 at 11:24
  • @Vlad FWIW: `ostream` almost certainly does allocate memory dynamically, probably on the first output. That memory will be freed in the destructor. Of course, the destructor of `std::cout` is never called, so that memory is never freed. But since there is only a small, finite number of such objects, and they only allocate memory once, there's no memory leak. – James Kanze Jul 05 '12 at 11:36
  • @JamesKanze *Of course, the destructor of std::cout is never called* why? – Luchian Grigore Jul 05 '12 at 11:38
  • @James: my comment was about "you can't have a memory leak if you don't use `new`". Apparently, if you use someone's code, you can never be sure you are not using `new` indirectly. – Vlad Jul 05 '12 at 11:52
  • @Vlad but usually this comes well documented. And if it doesn't, that's a bad library. – Luchian Grigore Jul 05 '12 at 11:55
  • @Luchian: are you sure STL is documented so good? I've never seen anything which explains whether e.g. `std::map` will or will not allocate on lookup. (Imagine that it's using a kind of cache for speed-up of frequent lookups -- is that prohibited?) – Vlad Jul 05 '12 at 11:59
  • @Vlad I'm not saying std doesn't allocate memory. But if it does (when it does), it manages it itself. – Luchian Grigore Jul 05 '12 at 12:01
  • 2
    @LuchianGrigore Because the standard says so. Basically, it wants to guarantee that you can use things like `std::cerr` in destructors. Including the destructors of static objects. – James Kanze Jul 05 '12 at 12:26
  • @Vlad In practice, no. You can never be sure of third party libraries. Of course, if the library is widely used, it's probably been sufficiently stress tested. (Although you never know---the implementation of `std::string` in g++ has at least one bug involving threading, and I don't know of anything more widely used.) – James Kanze Jul 05 '12 at 12:29
3

No, there is no memory leak.

Arrays use automatic storage which gets automatically freed when they go out of scope.

Using dynamic storage via new will cause a memory leak however:

int main(int argc, char *argv[]) {
    new f[1000]; // this leaks
}

And can someone explain how this small program works?

Constructing an array calls the default constructor for each element of the array. So f() is just being called 1000 times.

Pubby
  • 51,882
  • 13
  • 139
  • 180
  • 2
    Actually, even in your example there is no memory leak. All reasonably current operating systems clean up the resources allocated by a program when said program terminates, and a c++ program terminates after falling off the end of main – Christian Stieber Jul 05 '12 at 11:20
  • 2
    @ChristianStieber there's no clear definition of what a memory leak is. Related: http://stackoverflow.com/questions/9921590/is-not-calling-delete-on-a-dynamically-allocated-object-always-a-memory-leak – Luchian Grigore Jul 05 '12 at 11:26
  • 1
    A program which doesn't loop somewhere can't leak memory. Even if there is a `new`, it won't be repeated an indefinite number of times. – James Kanze Jul 05 '12 at 11:34
1

You shouldn't even have to close the program, it terminates automatically. Must be something that your IDE does, or whatever you work with.

How it works? Class "f" has a constructor that increases a global variable and outputs it. He creates an array with 1000 instances of "f", which causes the above to happen 1000 times, once for every "f" in the array.

Christian Stieber
  • 9,954
  • 24
  • 23
  • You are right. May be something with the IDE or I did something. I ran the program again, it exited normally. –  Jul 05 '12 at 11:39
0

Whenever this is done

f n[i]

Constructor is f() is called. Since with every call global variable is being incremented. So for every object of f from 1 to 1000 , the value of n is printed.

Regarding memory leak, there is none. The array is a local variable and is destroyed when the program ends. In order to enable dynamic allocation, use new keyword.

gibraltar
  • 1,678
  • 4
  • 20
  • 33
0

There is no obvious memory leak in the program. You don't allocate any object dynamically and you can't forget to release anything.

What does happen is that you call the array constructor for the array n. This itself calls fear each array element the constructor f::f(). Therefore you get the output. Well there you have a loop, but not at language level.

harper
  • 13,345
  • 8
  • 56
  • 105