Do I have to delete memory in this case? - c++

Here is a simple program using dynamic memory.
My question is do I have to delete the memory at the and or the struct will take care of it for me?
#include <iostream>
struct Student {
int grade;
char *name;
};
void print(Student name);
int main() {
Student one;
one.grade = 34;
one.name = new char[12];
int i;
for (i = 0; i < 11; ++i) {
one.name[i] = 'a' + i;
}
one.name[i] = '\0';
print(one);
delete[] one.name;
return 0;
}
void print(Student name) {
std::cout << name.name << " has a score of " << name.grade << "\n";
}

There is a simple rule of thumb- for each call of new you should have one call of delete. In this case you should delete one.name like so : delete [] one.name.
Of course you should do that after you no longer need its value. In this case this is immediately before the return.

Memory allocated dynamically using new or malloc must be freed up when you're done with it using delete or free otherwise you'll get Memory leak.
Make difference between delete and delete[]: the first without subscript operator is used to deleted dynamic memory allocated with new for a pointer. The latter is used for deleting an array allocated dynamically.
So in your case:
one.name = new char[12]; // an array of 12 elements in the heap
delete[] one.name; // freeing up memory
char* c = new char('C'); // a single char in the heap
delete c;
Don't mix new, delete with malloc, free:
This is undefined behavior, as there's no way to reliably prove that memory behind the pointer was allocated correctly (i.e. by new for delete or new[] for delete[]). It's your job to ensure things like that don't happen. It's simple when you use right tools, namely smart pointers. Whenever you say delete, you're doing it wrong.

If you don't want to use unique/shared pointers, you could use a constructor for allocating and a destructor for automatically freeing memory.

If the raw pointer in your structure is an observing pointer, you don't have to delete the memory (of course, someone somewhere in the code must release the memory).
But, if the raw pointer is an owning pointer, you must release it.
In general, every call to new[] must have a matching call to delete[], else you leak memory.
In your code, you invoked new[], so you must invoke delete[] to properly release the memory.
In C++, you can avoid bug-prone leak-prone raw pointers, and use smart pointers or container classes (e.g. std::vector, std::string, etc.) instead.

Creating a Structure does not mean it will handle garbage collection in C++
there is no garbage collection so for every memory you allocate by using new you should use delete keyword to free up space. If you write your code in JAVA you wont have to delete as garbage collector will automatically delete unused references.

Actually the structure won't freeup or delete the memory that you have been created. if in case you want to freeup the space you can do as follows.
#include <iostream>
using namespace std;
int main()
{
char *c = new char[12];
delete[] c;
return(0);
}

Related

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.

C++ char[] memory leak?

I'm new to C++ (porting from Java), and I cannot understand whether or not I have a memory leak in my code.
this is the basis of my code (it's far more complicated, I bring the important places where memory can leak)
char message[15000];
char allMessages[102400];
int allMessagesCounter;
int main() {
connect() \\this works just fine
openThreadAndGetAllMessages() \\ here I get each time a message to my message char array and concatenate it into allMessages array using allMessagesCounter
cout << allMessages;
disconnect() \\works just fine as well
}
My question is, do I need to free the message[] and allMessages[]?
Thanks!
No. In general, in C++, if you use the keyword new then you should also delete later. Your variables are allocated statically, and do not need to be deleted.
No you do not because they are not dynamically allocated. You only need to call delete if memory is allocated with new:
int *a = new int [5]; //must call delete [] or memory leak
int b [5]; //no need

array of questions on pointers, double pointers, malloc, realloc and new (to set the record straight)

I'm catching up on pointers. I wrote down a few lines of code to test the different ways I could dynamically allocate a 2d array (posted at the bottom)
My questions are the following:
Should I use malloc in c++, or new? If I use new, can I still use realloc?
When should I use realloc? What are the implications of using it in terms of performance and bugs?
Out of the examples bellow, which objectNew version should I use? If the answer depends on the application, what are does it depend on?
Many thanks,
Matt
#include <stdio.h>
#include <stdlib.h>
struct myObject
{
int data;
myObject(int i)
{
data = i;
}
myObject()
{
data = 0;
}
};
int main(){
int r = 7;
int c = 6;
printf("Objects using NEW===============================\n");
//notice the triple pointer being assigned a new double pointer array
myObject*** objectNew = new myObject** [r];
for(int i=0;i<r;i++)
{
//objectNew is a 1D array of double pointers, however if we assign another layer of pointers, it becomes a 2D array of pointers to myObject
objectNew[i] = new myObject* [c];
for(int j=0;j<c;j++){
objectNew[i][j] = new myObject(10*i+j);
//notice that we dereference data (->)
printf("objectNew[%2d][%2d]=%02d\n",i,j,objectNew[i][j]->data);
}
}
delete objectNew;
printf("Objects using NEW version 2===============================\n");
//notice the triple pointer being assigned a new double pointer array
myObject** objectNew2 = new myObject* [r];
for(int i=0;i<r;i++)
{
//objectNew is a 1D array of double pointers, however if we assign another layer of pointers, it becomes a 2D array of pointers to myObject
objectNew2[i] = new myObject [c];
for(int j=0;j<c;j++){
objectNew2[i][j] = myObject(10*i+j);
//notice that we dereference data (->)
printf("objectNew2[%2d][%2d]=%02d\n",i,j,objectNew2[i][j].data);
}
}
delete objectNew2;
printf("Objects using MALLOC===============================\n");
//notice the double pointer being allocated double pointers the size of pointers to myObject
myObject** objectMalloc =(myObject**) malloc(sizeof(myObject*)*r);
for(int i=0;i<r;i++)
{
//now we are assigning array of pointers the size of myObject to each double pointer
objectMalloc[i] = (myObject*) malloc(sizeof(myObject)*c);
for(int j=0;j<c;j++){
objectMalloc[i][j] = myObject(10*i+j);
//notice that we access data without dereferencing (.)
printf("objectMalloc[%2d][%2d]=%02d\n",i,j,objectMalloc[i][j].data);
}
}
free((void*) objectMalloc);
//same as Malloc
printf("Objects using CALLOC===============================\n");
myObject** objectCalloc = (myObject**) calloc(r,sizeof(myObject*));
for(int i=0;i<r;i++)
{
objectCalloc[i] = (myObject*) calloc(c,sizeof(myObject));
for(int j=0;j<c;j++){
objectCalloc[i][j] = myObject(10*i+j);
printf("objectCalloc[%2d][%2d]=%02d\n",i,j,objectCalloc[i][j].data);
}
}
free((void*) objectCalloc);
printf("Int using NEW===============================\n");
//int is not an object
int** intNew = new int* [r];
for(int i=0;i<r;i++)
{
intNew[i] = new int[c];
for(int j=0;j<c;j++){
intNew[i][j] = 10*i+j;
printf("intNew[%2d][%2d]=%02d\n",i,j,intNew[i][j]);
}
}
delete intNew;
printf("Int using malloc===============================\n");
int** intMalloc =(int**) malloc(sizeof(int*)*r);
for(int i=0;i<r;i++)
{
intMalloc[i] =(int*) malloc(sizeof(int)*c);
for(int j=0;j<c;j++){
intMalloc[i][j] = 10*i+j;
printf("intMalloc[%2d][%2d]=%02d\n",i,j,intMalloc[i][j]);
}
}
free((void*) intMalloc);
getchar();
return 0;
}
new and new[] are constructor aware, the C memory allocation functions are not.
Similarly, delete and delete [] are destructor aware, whereas free isn't.
realloc does not work with memory allocated with new, there is no standards defined analog to the realloc function with C++ memory management functions.
Do not mix new and delete with malloc/calloc/realloc and free (i.e. don't free any memory allocated with new, don't delete any memory allocated with malloc)
If you are doing new [], you most likely should be using an std::vector, which encapsulates all that memory management for you.
If you are using memory allocated raw pointers, you might be better served using smart/semi-smart pointers like boost::shared_ptr or boost::scoped_ptr or std::auto_ptr, depending on your needs.
Thanks to David Thornley for bringing this up:
Never mix scalar new and delete with their array forms, i.e. don't delete[] memory allocated with new, and don't delete memory allocated with new[]. Undefined behavior all around.
In your example, you SHOULD use new and new[] if you must, because as I said, they are constructor aware, and your class is not a POD data type since it has a constructor.
Please see the C++ FAQ for more information:
C++ FAQ Freestore Management
1) Should I use malloc in c++, or new?
If I use new, can I still use realloc?
Use new. And never use realloc with new.
When should I use realloc? What are
the implications of using it in terms
of performance and bugs?
Instead of using realloc, I usually implement my own memory-pool, from which I reallocate memory when I need it. This also improves performance.
Should I use malloc in c++, or new? If
I use new, can I still use realloc?
You can use malloc in C++; however, it is strongly discouraged in most circumstances. Additionally, if you call malloc, calloc, realloc, etc., you need to use free to deallocate the memory when done.
If you use new to allocate memory, you must use delete to deallocate it.
The C-allocation routines do not have type safety. new does.
If you want to write C++ (!!) programs don't use malloc, realloc, free. It is just not C++ functions.
And there is no necessity to use new is your cases (I'm talking about the example).
You should use vector or some other containter.
In general, you should try to avoid doing your own memory allocation in C++. Most (not all) arrays can be done with std::vector better than you're going to do your own, particularly since you are making a mistake here.
You allocate, say, intNew and intNew[i]. Then you delete [] intNew; (the brackets are necessary here, leaving them off is an error), without delete []ing any of the intNew[i]. The one-dimensional arrays you allocated are now memory leaks, and cannot possibly be freed because you've lost all references to them. Neither C nor C++ normally come with a garbage collector.
The C memory allocation functions deal with memory only. They aren't type-safe, and don't call constructors or destructors. They can be used with data types that require neither, but you do have to make sure they do neither. (It is possible to malloc memory and use placement new to create objects there, but that's more advanced.)
The C++ memory allocation functions deal with memory and objects. They are type-safe, mostly, and do call constructors and destructors. Not all objects can be moved safely, so there is no equivalent of malloc. The tricky part is that you have to match new with delete, and new[] with delete[]. You have this error in your code: delete intNew; should be delete [] intNew;.

Does strcpy'ing a string into into a larger char array cause a memory leak?

Hey all, just wondering whether the following would cause a memory leak?
char* a = "abcd"
char* b = new char[80];
strcpy(b, a);
delete[] b;
Will it delete the whole block of 80 or just the 4 characters copied into it by strcpy? Thanks!
You allocated 80 bytes into b, so delete[] will free 80 bytes. What you did with the array in the meantime is irrelevant.
(Unless, of course, you corrupted the heap, in which case delete[] will probably crash.)
EDIT: As others have pointed out, since b is an array, you need to use delete[] b; instead of delete b;. Some implementations might let you get away with that, but others won't, and it would still be wrong.
A memory leak is when you don't free memory. Just because you allocated more than you need doesn't mean it a memory leak. What you do with your memory is up to you.
Though that should 1) be delete [] b;, or you get undefined behavior, and 2) Be a std::string or std::vector, so you don't both manage and use a resource.
The allocation system will take care of remembering how long the allocations are. The contents don't matter at all.
However, you do need to call the right delete operator. In this case since you allocated new[] you need to delete[].
The last line should be:
delete[] b;
If you allocate one item use delete, if you're allocating an array use delete[].
Since this is tagged C++, here's the C++ version - good to understand memory management via new/delete, but better to avoid doing it by hand using RAII.
#include <string>
#include <iostream>
using namespace std;
int main()
{
string a("abcd");
string aCopy(a);
cout << aCopy << endl;
const char* b(aCopy.c_str());
cout << b << endl;
}

Is delete p where p is a pointer to array always a memory leak?

following a discussion in a software meeting I've set out to find out if deleting a dynamically allocated, primitives array with plain delete will cause a memory leak.
I have written this tiny program and compiled it with visual studio 2008 running on windows XP:
#include "stdafx.h"
#include "Windows.h"
const unsigned long BLOCK_SIZE = 1024*100000;
int _tmain()
{
for (unsigned int i =0; i < 1024*1000; i++)
{
int* p = new int[1024*100000];
for (int j =0;j<BLOCK_SIZE;j++) p[j]= j % 2;
Sleep(1000);
delete p;
}
}
I than monitored the memory consumption of my application using task manager, surprisingly the memory was allocated and freed correctly, allocated memory did not steadily increase as was expected
I've modified my test program to allocate a non primitive type array :
#include "stdafx.h"
#include "Windows.h"
struct aStruct
{
aStruct() : i(1), j(0) {}
int i;
char j;
} NonePrimitive;
const unsigned long BLOCK_SIZE = 1024*100000;
int _tmain()
{
for (unsigned int i =0; i < 1024*100000; i++)
{
aStruct* p = new aStruct[1024*100000];
Sleep(1000);
delete p;
}
}
after running for for 10 minutes there was no meaningful increase in memory
I compiled the project with warning level 4 and got no warnings.
is it possible that the visual studio run time keep track of the allocated objects types so there is no different between delete and delete[] in that environment ?
delete p, where p is an array is called undefined behaviour.
Specifically, when you allocate an array of raw data types (ints), the compiler doesnt have a lot of work to do, so it turns it into a simple malloc(), so delete p will probably work.
delete p is going to fail, typically, when:
p was a complex data type - delete p; won't know to call individual destructors.
a "user" overloads operator new[] and delete[] to use a different heap to the regular heap.
the debug runtime overloads operator new[] and delete[] to add extra tracking information for the array.
the compiler decides it needs to store extra RTTI information along with the object, which delete p; won't understand, but delete []p; will.
No, it's undefined behavior. Don't do it - use delete[].
In VC++ 7 to 9 it happens to work when the type in question has trivial destructor, but it might stop working on newer versions - usual stuff with undefined behavior. Don't do it anyway.
It's called undefined behaviour; it might work, but you don't know why, so you shouldn't stick with it.
I don't think Visual Studio keeps track of how you allocated the objects, as arrays or plain objects, and magically adds [] to your delete. It probably compiles delete p; to the same code as if you allocated with p = new int, and, as I said, for some reason it works. But you don't know why.
One answer is that yes, it can cause memory leaks, because it doesn't call the destructor for every item in the array. That means that any additional memory owned by items in the array will leak.
The more standards-compliant answer is that it's undefined behaviour. The compiler, for example, has every right to use different memory pools for arrays than for non-array items. Doing the new one way but the delete the other could cause heap corruption.
Your compiler may make guarantees that the standard doesn't, but the first issue remains. For POD items that don't own additional memory (or resources like file handles) you might be OK.
Even if it's safe for your compiler and data items, don't do it anyway - it's also misleading to anyone trying to read your code.
no, you should use delete[] when dealing with arrays
Just using delete won't call the destructors of the objects in the array. While it will possibly work as intended it is undefined as there are some differences in exactly how they work. So you shouldn't use it, even for built in types.
The reason seems not to leak memory is because delete is typically based on free, which already knows how much memory it needs to free. However, the c++ part is unlikely to be cleaned up correctly. I bet that only the destructor of the first object is called.
Using delete with [] tells the compiler to call the destructor on every item of the array.
Not using delete [] can cause memory leaks if used on an array of objects that use dynamic memory allocations like follows:
class AClass
{
public:
AClass()
{
aString = new char[100];
}
~AClass()
{
delete [] aString;
}
private:
const char *aString;
};
int main()
{
AClass * p = new AClass[1000];
delete p; // wrong
return 0;
}