creating object on stack/heap - c++

I have two piece of code that creates an A object
A* a=new A();
AND
A b;
A *c=&b;
The question is: someone says "objects are always allocated on heap"?
Is it true even declare it on stack?(Code 1)
Note: I am referring to the actual memory allocation. I know object 'b' will be
cleared when it goes out the the scope. But when it is still in scope, where does the
memory of 'b' actually reside?

Pointer a is on stack, the instance of A it points to is on heap.
Object b is on stack, pointer c is on stack.

#LouisTan it depends where these lines of code are located in program. But in general this pointer will be on Stack.
compare this:
/* my.c */
char * str = "Your dog has fleas."; /* 1 */
char * buf0 ; /* 2 */
int main(){
char * str2 = "Don't make fun of my dog." ; /* 3 */
static char * str3 = str; /* 4 */
char * buf1 ; /* 5 */
buf0 = malloc(BUFSIZ); /* 6 */
buf1 = malloc(BUFSIZ); /* 7 */
return 0;
}
This is neither allocated on the stack NOR on the heap. Instead it's allocated as static data, and put into it's own memory segment on most modern machines. The actual string is also being allocated as static data, and put into a read-only segment in right-thinking machines.
is simply a static alocated pointer; room for one address, in static data.
has the pointer allocated on the stack, and will be effectively deallocated when main returns. The string, since it's a constant, is allocated in static data space along with the other strings.
is actually allocated exactly like at 2. The static keyword tells you that it's not to be allocated on the stack.
...but buf1 is on the stack, and
... the malloc'ed buffer space is on the heap.
And by the way., kids don't try this at home. malloc has a return value of interest; you should always check the return value.
see here full Charlie Martin post

As a general rule of thumb:
If you use any kind of dynamic memory allocation (new, array new, malloc etc), the allocated object will be located on the heap. Else, it is pushed onto the stack.

It is definite possible to create objects on local scope (using stack memory) just as you have shown on the second snippet.
The first snippet creates object A using heap memory.
Kevin

Related

Check after malloc & before calling free()

I have read this post about check before calling free(). I want to further confirm through a case.
The following codes are copied from my C++ project (tested, no error/warning). I just want to confirm the right way to check memory allocation and free() in C++.
// part 1: declare
typedef struct cipher_params_t {
unsigned char * p1;
int p2;
}cipher_params_t;
// part 2: allocate memory
cipher_params_t *params = (cipher_params_t*)malloc(sizeof(cipher_params_t));
// part 3: check allocate memory
if (!params) {
/* Unable to allocate memory on heap*/
fprintf(stderr, "ERROR: malloc error: %s\n", strerror(errno));
return errno;
}
// part 4: assign values
unsigned char key[16] = {0x01, 0x02, ..., 0x0f};
params -> p1 = key;
params -> p2 = 1;
// part 5: use params for some function
some_func(params);
// part 6: free params lastly
cleanup1(params);
// cleanup2(params); //another option
void cleanup1 (cipher_params_t *params){
if(params) free(params)
}
void cleanup2 (cipher_params_t *params){
if(params!=NULL) free(params)
}
Questions:
In part 3, is this the correct way to check if(!params). Any error is not considered here?
In part 6, I give 2 options - if(params) and if(params!=NULL). Are they same?
In part 1, struct includes pointer(p1) and non-pointer(p2). What is the difference between free a pointer, free a non-pointer, and free a combination of both?
If I use delete[ ] instead of free(). How? and what's the difference?
In part 3, is this the correct way to check if(!params). Any error is not considered here?
Yes this is correct since malloc() returns NULL on failure.
In part 6, I give 2 options - if(params) and if(params!=NULL). Are they same?
Yes, they are the same. But in C++ there is several reasons to use nullptr (a proper type nullptr_t) instead of NULL.
In part 1, struct includes pointer(p1) and non-pointer(p2). What is the difference between free a pointer, free a non-pointer, and free a combination of both?
In fact, you don't and can't release a non-pointer. In your case, you are releasing only one pointer that is a pointer to a cipher_params_t structure.
With malloc() you allocates memory for containing a cipher_params_t whatever the contents is, you just allocate enough space for containing it. And when you free(), you release the allocated memory, no matter what the structure contains.
Please note that malloc() and free() don't call contructors/destructors, neither for the pointed structure, nor for its contents. They are just reserving/allocating memory space.
If I use delete[ ] instead of free(). How? and what's the difference?
Never ever mix malloc()/free(), new/delete and new[]/delete[] because they don't do the same thing. You should read What is the difference between new/delete and malloc/free? for more information.
Regarding the question:
In part 1, struct includes pointer(p1) and non-pointer(p2). What is
the difference between free a pointer, free a non-pointer, and free a
combination of both?
in the example you gave you are deleting a struct from heap mem. This struct has a pointer (assuming 8 bytes) and an int (usually 4 bytes) so you delete this piece of memory (12 bytes) and nothing else.
The memory where the pointer is pointing will remain there, so the key[16] won't be touched. In your example there is a possible issue, as params it's on heap and key is in stack, stack will be deleted when you leave scope but params pointer could still point to it.

My C program is crashing when I call a method from a class instance here is the code

here is the class that I am using.
#include<stdio.h>
#include <string.h>
class EnDe{
private:
int *k;
char *temp;
public:
char * EncryptString(char *str);
char * DecryptString(char *str);
EnDe(int *key);};
EnDe::EnDe(int *key){
k=key;
}
char * EnDe::EncryptString(char *str){
int t=2;
t=(int)k[1]*(int)2;
for (int i=0;i<strlen(str);i++){
temp[i]=str[i]+k[0]-k[2]+2-k[1]+k[3]+t;
}
char alp=k[0]*57;
for (int y=strlen(str);y<strlen(str)+9;y++){ //--*
temp[y]=alp+y; //--*
}
temp[(strlen(str)+9)]='\0'; //--*
return temp;
}
char * EnDe::DecryptString(char *str){
int t=2;
t=k[1]*2;
for (int i=0;i<strlen(str);i++){
temp[i]=str[i]-t-k[3]+k[1]-2+k[2]-k[0];
}
temp[(strlen(str)-9)]='\0';
return temp;
}
And here is the main program.
#include <stdio.h>
#include "EnDe.h"
int main(void){
char *enc;
char op;
printf("\nE to encrypt and D to decrypt");
int opi[4]={1,2,9,1};
EnDe en(opi);
strcpy(enc,en.EncryptString("It is C's Lounge!! "));
printf("Encrypted : %s",enc);
return 0;
}
Something is wrong with en.EncryptString function
when I run the program it stops working giving error and on removing strcpy(enc,en.EncryptString("It is C's Lounge!! ")); it runs. I want this problem to be resolved.
char *enc;
strcpy(enc,en.EncryptString("It is C's Lounge!! "));
You don't provide any space for the copy - enc doesn't point anywhere.
You never allocate any memory.
When you say
char *foo;
You tell the compiler that you want to store a memory address to some data somewhere, but not that you also want to store some data. Your class stores two pointers (int *k and char *temp) that never get any memory assigned to them, and so does your main function with char *enc. This can never work.
In C and C++, there are two modes of memory allocation: one is stack-based allocation, where you declare variable names in a function, and the compiler or the runtime will automatically allocate and release memory for you; the other is heap-based allocation, where you use malloc or new to allocate memory at run time, and must manually release that memory again with delete or free.
A pointer is "just" a stack-allocated variable that contains the address of another memory location. If you don't assign any value to a pointer, it points to invalid memory, and whatever you try to do with it will fail. To fix your program, you must make sure that every pointer points to valid memory. If you want it to point to a stack-based variable, you use the address-of operator:
int val = 4;
int *pointer_to_val = &val;
/* the pointer_to_val variable now holds the address of the val variable */
If you don't want it to point to a stack-allocated variable, you must allocate the memory yourself.
In C++, heap memory is allocated with the new operator, like so:
ClassType *instance = new ClassType(arg1, arg2)
where ClassType is the type of the class you're creating an instance of, instance is the pointer where you want to store the address of the instance you've just created, and arg1 and arg2 are arguments to the ClassType constructor that you want to run.
When you no longer need the allocated memory, you use delete to release the memory:
delete instance;
Alternatively, you can also use the C-style malloc and free functions. These are not operators; they are functions which return the address of the allocated memory. They do not work for C++ class instances (since you do not run the constructor over the returned memory), but if you want to run a pure-C program, they're all you have. With malloc, you do as follows:
char* string = malloc(size);
where string is the pointer for which you want to allocate memory, and size is the number of bytes you want the system to allocate for you. Once you're ready using the memory, you release it with free:
free(string);
When calling delete or free, it is not necessary to specify the size of the object (the system remembers that for you). Note, however, that you must make sure to always use delete for memory allocated with new, and to always use free for memory allocated with malloc. Mixing the two will result in undefined behaviour and possibly a crash.

How to manage memory in functions C++

How to manage memory in function, which returns dynamically allocated variable?
What happens with buffer, when function returns?
char * getStr(){
char * buffer = new char[12];
sprintf_s(buffer, 12 , "abcdef");
return buffer;
}
buffer stays allocated, but luckily you're returning the pointer.
You must delete[] that pointer at some point, else you'll leak memory.
Notice how I've used []: that's important. This balances your allocation of an array of chars. (Conceptually the runtime stores the length of an array allocated with new something[], and delete[] informs the runtime to free the correct number of elements.)
When function returns, your buffer still exists. There is nothing like embedded memory manager, you MUST free all the memory you allocated manualy. That is about C.
In C++ standart library, there is objects called smart pointers. With the pressence of exceptions, they are totally recommended to use. There is fine answer on SO about them: What is a smart pointer and when should I use one?
Nothing.
The address which is stored in *buffer will be returned to the caller and it is up to the caller to delete the memory again.
buffer is a pointer that means it addresses a point in memory.
new will allocate a bloc of memory, for the command new char[12] it will allocate 12 chars worth of memory.
new returns the address of the memory and that is assigned to your pointer buffer.
Note that because you only have a pointer to the memory, you need to clean that up before buffer goes out of scope. If the address contained in buffer buffer goes out of scope you will have "leaked" memory. Because it cannot be reclaimed. You clean up the memory allocated by new char[12] with the command: delete[].
Thank to Bathsheba for his answer.
My vision of a solution to the problem:
char * getStr(){
char * buffer = new char[12];
sprintf_s(buffer, 12 , "abcdef");
return buffer;
}
int _tmain(int argc, _TCHAR* argv[]){
char * p = getStr();
std::cout << p << std::endl;
delete[] p;
return 0;
}

Does this produce a memory leak?

I'm following a book on C++ programming, and I'm following the exercises. One exercise asks me to create a program that produces a memory leak. Will this program produce such a leak?
int main()
{
int * pInt = new int;
*pInt = 20;
pInt = new int;
*pInt =50;
return 0;
}
Considering it is a trivial example, not having a delete paired with your new is a leak. In order to prevent a leak in this case you would need the following:
int * pInt = new int;
*pInt = 20;
delete pInt ;
pInt = new int;
*pInt =50;
delete pInt ;
A decent tool to use to detect memory leaks is Valgrind. I ran the tool on your sample code, like so:
valgrind ./a.out
and this is part of the output it produced:
==14153== HEAP SUMMARY:
==14153== in use at exit: 8 bytes in 2 blocks
==14153== total heap usage: 2 allocs, 0 frees, 8 bytes allocated
==14153==
==14153== LEAK SUMMARY:
==14153== definitely lost: 8 bytes in 2 blocks
Which confirms that indeed the program does leak memory.
Yes. To avoid leaks, every time you call new, you have to have a matching call to delete. You have 2 calls to new and no calls to delete, so you have 2 leaks.
Note that when your program exits, the OS will free up all the memory you've allocated with new. So memory leaks are really only a problem for non-trivial programs.
One exercise asks me to create a program that produces a memory leak.
Will this program produce such a leak?
an utter exercise , and your code is a better answer to exercise !
Pointers and memory leaks. These are truly the items that consume most of the debugging time for developers
Memory leak
Memory leaks can be really annoying. The following list describes some scenarios that result in memory leaks.
Reassignment, I'll use an example to explain reassignment.
char *memoryArea = malloc(10);
char *newArea = malloc(10);
This assigns values to the memory locations shown in Figure 4 below.
http://www.ibm.com/developerworks/aix/library/au-toughgame/fig4.gif
Figure 4. Memory locations
memoryArea and newArea have been allocated 10 bytes each and their respective contents are shown in Figure 4. If somebody executes the statement shown below (pointer reassignment )
memoryArea = newArea;
then it will surely take you into tough times in the later stages of this module development.
In the code statement above, the developer has assigned the memoryArea pointer to the newArea pointer. As a result, the memory location to which memoryArea was pointing to earlier becomes an orphan, as shown in Figure 5 below. It cannot be freed, as there is no reference to this location. This will result in a memory leak of 10 bytes.
http://www.ibm.com/developerworks/aix/library/au-toughgame/fig5.gif
Figure 5. Memory leak
Before assigning the pointers, make sure memory locations are not becoming orphaned.
Freeing the parent block first
Suppose there is a pointer memoryArea pointing to a memory location of 10 bytes. The third byte of this memory location further points to some other dynamically allocated memory location of 10 bytes, as shown in Figure 6.
http://www.ibm.com/developerworks/aix/library/au-toughgame/fig6.gif
Figure 6. Dynamically allocated memory
free(memoryArea)
**If memoryArea is freed by making a call to free, then as a result the newArea pointer also will become invalid. The memory location to which newArea was pointing cannot be freed, as there is no pointer left pointing to that location. In other words, the memory location pointed by newArea becomes an orphan and results in memory leak.
Whenever freeing the structured element, which in turn contains the pointer to dynamically allocated memory location, first traverse to the child memory location (newArea in the example) and start freeing from there, traversing back to the parent node.
The correct implementation here will be:
free( memoryArea->newArea);
free(memoryArea);
Improper handling of return values
At time, some functions return the reference to dynamically allocated memory. It becomes the responsibility of the calling function to keep track of this memory location and handle it properly.**
char *func ( )
{
return malloc(20); // make sure to memset this location to ‘\0’…
}
void callingFunc ( )
{
func ( ); // Problem lies here
}
In the example above, the call to the func() function inside the callingFunc() function is not handling the return address of the memory location. As a result, the 20 byte block allocated by the func() function is lost and results in a memory leak.
Sharp Reference at :
http://www.ibm.com/developerworks/aix/library/au-toughgame/
Update:
your interest let me for an edit
Simple rules to avoid Memory Leaks in C
You are allocating memory for p and q:
p=new int [5];
/* ... */
q=new int;
But you are only freeing p using an invalid operator, since arrays should be deleted using delete[]. You should at some point free both p and q using:
delete[] p;
delete q;
Note that since you are making your pointers point to the other pointer's allocated buffer, you might have to check which delete operator corresponds to which new operation.
You should use delete[] on the buffer allocated with new[] and delete with the buffer allocated with new.
Rule 1: Always write “free” just after “malloc”
int *p = (int*) malloc ( sizeof(int) * n );
free (p);
Rule 2: Never, ever, work with the allocated pointer. Use a copy!
int *p_allocated = (int*) malloc ( sizeof(int) * n );
int *p_copy = p_allocated;
// do your stuff with p_copy, not with p_allocated!
// e.g.:
while (n--) { *p_copy++ = n; }
...
free (p_allocated);
Rule 3: Don’t be parsimonious. Use more memory.
Always start by allocating more memory than you need. After you finish debugging, go back and cut on memory use. If you need an array 1000 integers long, allocate 2000, and only after you make sure everything else is OK – only then go back and cut it down to 1000.
Rule 4: Always carry array length along with you
Wherever your array goes, there should go with it it’s length. A nice trick is to allocate an array sized n+1, and save n into it’s 0 place:
int *p_allocated = (int*) malloc ( sizeof(int) * (n+1) );
int *p_copy = p_allocated+1;
p_copy[-1] = n;
// do your stuff with p_copy, not with p_allocated!
free (p_allocated);
Rule 5: Be consistent. And save comments
The most important thing is to be consistent and to write down what you do. I am always amazed at how many programmers seem to think that comments are a waste of time. They are imperative. Without comments, you probably won’t remember what you did. Imagine returning to your code a year after you wrote it, and spending countless hour trying to recall what that index does. Better to spend a couple of seconds writing it down.
Also, if you are consistent, you will not fail often. Always use the same mechanism for passing arrays and pointers. Don’t change the way you do things lightly. If you decide to use my previous trick, use it everywhere, or you might find yourself referring back to a nonexistent place because you forgot what type of reference you chose.
Ref : http://mousomer.wordpress.com/2010/11/03/simple-rules-to-avoid-memory-leaks-in-c/
Yes, this produces not one, but two memory leaks: both allocated ints are leaked. Moreover, the first one is leaked irrecoverably: once you assign pInt a new int the second time, the first allocated item is gone forever.
Will this program produce suck a leak?
Yes, it will.
Yes and no. When pInt is overwritten with a new int pointer, you lose that memory that was previously allocated, however when the program returns, most modern operating systems will clean up this memory, as well as the memory lost by not deallocating pInt at the end.
So in essence, yes, something like this will result in two memory leaks.
It does, because you allocate space with the statement "new int", but do not use "delete" to free the space.

Global memory management in C++ in stack or heap?

If I declare a data structure globally in a C++ application , does it consume stack memory or heap memory ?
For eg
struct AAA
{
.../.../.
../../..
}arr[59652323];
Since I wasn't satisfied with the answers, and hope that the sameer karjatkar wants to learn more than just a simple yes/no answer, here you go.
Typically a process has 5 different areas of memory allocated
Code - text segment
Initialized data – data segment
Uninitialized data – bss segment
Heap
Stack
If you really want to learn what is saved where then read and bookmark these:
COMPILER, ASSEMBLER, LINKER AND LOADER: A BRIEF STORY (look at Table w.5)
Anatomy of a Program in Memory
The problem here is the question. Let's assume you've got a tiny C(++ as well, they handle this the same way) program like this:
/* my.c */
char * str = "Your dog has fleas."; /* 1 */
char * buf0 ; /* 2 */
int main(){
char * str2 = "Don't make fun of my dog." ; /* 3 */
static char * str3 = str; /* 4 */
char * buf1 ; /* 5 */
buf0 = malloc(BUFSIZ); /* 6 */
buf1 = malloc(BUFSIZ); /* 7 */
return 0;
}
This is neither allocated on the stack NOR on the heap. Instead, it's allocated as static data, and put into its own memory segment on most modern machines. The actual string is also being allocated as static data and put into a read-only segment in right-thinking machines.
is simply a static allocated pointer; room for one address, in static data.
has the pointer allocated on the stack and will be effectively deallocated when main returns. The string, since it's a constant, is allocated in static data space along with the other strings.
is actually allocated exactly like at 2. The static keyword tells you that it's not to be allocated on the stack.
...but buf1 is on the stack, and
... the malloc'ed buffer space is on the heap.
And by the way., kids don't try this at home. malloc has a return value of interest; you should always check the return value.
For example:
char * bfr;
if((bfr = malloc(SIZE)) == NULL){
/* malloc failed OMG */
exit(-1);
}
Usually it consumes neither. It tries to allocate them in a memory segment which is likely to remain constant-size for the program execution. It might be bss, stack, heap or data.
Neither. It is .data section.
Global memory is pre-allocated in a fixed memory block, or on the heap, depending on how it is allocated by your application:
byte x[10]; // pre-allocated by the compiler in some fixed memory block
byte *y
main()
{
y = malloc(10); // allocated on the heap
}
EDIT:
The question is confusing: If I allocate a data structure globally in a C++ application , does it consume stack memory or heap memory ?
"allocate"? That could mean many things, including calling malloc(). It would have been different if the question was "if I declare and initialize a data structure globally".
Many years ago, when CPUs were still using 64K segments, some compilers were smart enough to dynamically allocate memory from the heap instead of reserving a block in the .data segment (because of limitations in the memory architecture).
I guess I'm just too old....
Neither declaring a data structure globally in a C++ consumes heap or stack memory. Actually, global variables are typically allocated in a data segment whose size remains unchanged during the whole program. Stacks and heaps are typically used for variables that get created and destroyed during executing the program.
The global object itself will take up memory that the runtime or compiler reserves for it before main is executed, this is not a variable runtime cost so neither stack nor heap.
If the ctor of the object allocates memory it will be in the heap, and any subsequent allocations by the object will be heap allocations.
It depends on the exact nature of the global object, if it's a pointer or the whole object itself that is global.
global variables live on the heap. these are a special case because they live for the life of the program
If you are explicitly allocating the memory yourself by new or malloc, then it will be allocated in heap. If the compiler is allocating the memory, then it will be allocated on stack.