3

I have been doing some research and still can't find a solution to my problem. As far as I know, when we declare variables outside of a function, they are allocated within the heap, and that memory is not freed until the end of execution; unless we specifically do so with the delete function. I've tried the following functions to free the variables declared at the beginning of the code and none of them worked (getting a debug error in dbgdel.cpp): delete, delete [], free(). What am I doing wrong?

I will paste underneath a summarized version of the code. Any help is appreciated. Thank you!

(I know global variables are not usually desirable in proper programming, but is not my piece of code, I am just trying to fix it as it is.)

#include <stdio.h>
#include <conio.h>
#include <cv.h>
#include <highgui.h>
#include <cxcore.h>
#include "Viewer.h"
....    
// Arrays
float z_base [5201][5201];
....

uchar maskThreshold [5200][5200];
...


void main(){
.....       
     delete [] z_base;
     //free (z_base);
     //delete z_base;
     //free (&z_base);    
} 
trincot
  • 317,000
  • 35
  • 244
  • 286
Nicolai
  • 333
  • 8
  • 15
  • 1
    Variables don't live "on the heap". Only *objects* do. – Kerrek SB Jan 21 '13 at 12:32
  • @KerrekSB: some variables are objects (specifically, variables that are not references are objects). So "only objects" might not be quite the right way to express that. – Steve Jessop Jan 21 '13 at 12:43
  • Actually, I'll take that back if we can establish that it's incorrect to refer to the object defined in a declaration like `int i = 0;` as "the variable". One could perhaps argue that a "variable" is not the object itself but rather is a compile-time entity having a name, and whose name refers to an object. – Steve Jessop Jan 21 '13 at 12:46
  • @SteveJessop: I think you got the cat and the man wrong. Variables *can* be objects. But dynamically allocated objects can never be variables, and variables can never by dynamic objects. (I elaborated on this a bit more [in this answer](http://stackoverflow.com/a/14413567/596781).) – Kerrek SB Jan 21 '13 at 14:03
  • @KerrekSB: that is what I thought, the word "variable" does properly refer to the object. Not a big deal, but saying "X isn't Y, only Z is" doesn't quite make sense when some Zs are in fact Xs. – Steve Jessop Jan 21 '13 at 14:41

3 Answers3

6

As far as I know, when I declare variables outside of every function they are allocated within the heap

This is not true. In general, you only have to call delete or delete[] if you have allocated memory with new or new [] respectively.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
4
  1. There is no heap (in C++).
  2. All memory is released at the end of execution.
  3. delete what you new, delete[] what you new[].
  4. void main is wrong (main must return int).

That is all.

melpomene
  • 84,125
  • 8
  • 85
  • 148
  • If there is no heap in C++, where does the memory that `new` allocates come from? – mah Jan 21 '13 at 12:13
  • 2
    @mah That's for `operator new` to decide. – R. Martinho Fernandes Jan 21 '13 at 12:13
  • @R.MartinhoFernandes -- it comes from the heap which you claim doesn't exist. There are very few memory pools in general systems... the heap, the stack, and static storage. – mah Jan 21 '13 at 12:16
  • @mah We're not talking about "general systems", we're talking about C++. And C++ simply says that objects created with `new` have dynamic storage. It doesn't talk about "pools" or "heaps" or anything. – melpomene Jan 21 '13 at 12:17
  • @mah C++ doesn't know anything about heaps, stacks, free stores and so on. – juanchopanza Jan 21 '13 at 12:18
  • 1
    We don't have to talk about general systems specifically, when we're talking about a language that runs on them. I'm saying that C++ allocates to the heap, and while you're technically correct when you decouple the heap from the language, you're playing word games when you suggest it doesn't exist -- especially when you aren't able to suggest a realistic alternative, don't you think? – mah Jan 21 '13 at 12:24
  • @juanchopanza Yes and no (excluding the library, of course). While the standard doesn't use the word "stack", the semantics of local variables and temporarys definitely require one. And "heap" is a more or less generic word for the free space arena, where memory is dynamically allocated. – James Kanze Jan 21 '13 at 12:24
  • @mah C++ isn't specified to run on anything in particular. I don't need to suggest an alternative to something that isn't part of C++ in the first place. – melpomene Jan 21 '13 at 12:28
  • @JamesKanze Local variables don't require a stack; you can put them on the heap instead. – melpomene Jan 21 '13 at 12:28
  • @melpomene you're playing word technicalities. What you're stating is certainly correct since the language spec doesn't care about where memory gets placed. However, what you're stating is also completely useless since while memory _could_ be managed in various other ways... it simply isn't (except in the most exceptional of cases). Someone like the question poster, trying to understand how to properly manage their memory, is not going to be helped with a statement such as "There is no heap (in C++)" -- especially without quite a bit more explanation. – mah Jan 21 '13 at 12:31
  • 2
    @mah I disagree. Understanding proper memory management in C++ does not require obscure details of a particular implementation. – melpomene Jan 21 '13 at 12:33
  • If this "particular implementation" were an uncommon one, or even something significantly less than "just about the only one, and certainly the only one most people are ever going to see" then I could agree with you. – mah Jan 21 '13 at 12:35
  • 1
    @melpomene It does require understanding the principles of stacks, since that is an essential part of the requirements, even if the name isn't used. ("Heap" is a bit more ambiguous, since it can refer to several different things; the word should probably be avoided unless a real heap data structure is meant, as in `std::push_heap` et al.) – James Kanze Jan 21 '13 at 12:46
  • @melpomene Local variables _must_ be on a stack. How that stack is implemented is not specified; I've actually seen a C compiler which allocated each stack frame dynamically. But the results are a stack. – James Kanze Jan 21 '13 at 12:48
  • 3
    Since we're playing: if the existence of a heap is a particular implementation detail irrelevant to the C++ standard, then so is the fact that all memory is released at the end of program execution. What the OS does at process termination (or what the hardware/bootloader/whatever does at program termination for OS-less implementations) is outside the scope of the standard. – Steve Jessop Jan 21 '13 at 12:48
  • @SteveJessop nice one! melpomene, a rebuttal? – Luchian Grigore Jan 21 '13 at 12:50
  • @LuchianGrigore No, I agree with SteveJessop. But in that case `delete` won't help you either because it won't necessarily release memory to the system; it may just mark it as reusable by `new`. – melpomene Jan 21 '13 at 13:04
  • @JamesKanze How are the results a stack? – melpomene Jan 21 '13 at 13:04
  • @melpomene calling a function equates to pushing a frame (however it is allocated is irrelevant) and returning from it to poping the top frame (and that makes the previous one the new top frame). That is a stack. – R. Martinho Fernandes Jan 21 '13 at 13:14
  • @melpomene Because they meet the definition of a stack: FILO. – James Kanze Jan 21 '13 at 13:45
  • @JamesKanze I don't see how they do that. You create variables - that imposes a linear order on creation. And then? There is no observable "out" operation. – melpomene Jan 21 '13 at 14:08
  • @R.MartinhoFernandes That's function calls, not variables. – melpomene Jan 21 '13 at 14:08
  • Local variables are in that stack. (how they are placed in it, whether directly or through pointers, is irrelevant) They have to be because they must be constructed and destroyed in a stack-like order. – R. Martinho Fernandes Jan 21 '13 at 14:13
  • @R.MartinhoFernandes No, they're not. – melpomene Jan 21 '13 at 14:14
  • @melpomene What do you mean: there is no observable "out" operation? What do you think calling the destructor is? (But even in C: the compiler must obey a FILO order with regards to variable creation between functions. As soon as a language supports recursive calls, it needs a stack.) – James Kanze Jan 21 '13 at 15:59
  • @JamesKanze Calling the destructor is a special case. You only need a stack for objects with a non-trivial destructor, and even then you technically only need it for the destructor calls themselves, not for memory (de-)allocation. As for C: "FILO order with regards to variable creation" makes no sense because there is still no "out" operation. – melpomene Jan 21 '13 at 16:04
  • @JamesKanze: Not strictly true. A stack is the easiest way to implement this. A good historical example is Russian Computer science. They did not introduce the concept of the stack into their languages until very late but they still had recursion. The compiler was designed to generate self modifying code (of course the code would build some form of internal structure to help in returning but it was not technically a stack as the way we think of it nowadays). – Martin York Jan 21 '13 at 16:18
  • @mah: Considering variables as going on the stack/heap is counter intuitive in C++ it does not help a newcomer (it just makes things more confusing). Where is `int x` allocated? stack or heap. No idea (it depends on the surrounding context). The concepts in C++ are static/automatic/dynamic storage duration objects. Teaching these concepts is more inline with the language and makes explaining variable lifespan much easier and intuitive. Explaining it in terms of stack and heap is a loosing battle especially as they have nothing to do with C++. http://stackoverflow.com/a/11712472/14065 – Martin York Jan 21 '13 at 16:22
  • @mah: An example of a machine with neither a stack or a heap: `Manchester dataflow machine` the architecture is: http://en.wikipedia.org/wiki/Dataflow_architecture yet it still has a C++ compiler. – Martin York Jan 21 '13 at 16:24
3

You don't. The run-time will do it for you. As a rule of thumb, you only need to delete/delete[] that which you allocated with new/new[].

Also, note that globals are not allocated on the heap, but in static memory.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • 1
    I know what you mean by static. But the word is so overloaded it is worth being a bit more explicit for newcomers and beginners. – Martin York Jan 21 '13 at 16:11