C++ char[] memory leak? - c++

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

Related

What is the difference between char array[50] and char *array = new char[50]? [duplicate]

This question already has answers here:
What is the difference between Static and Dynamic arrays in C++?
(13 answers)
Closed 1 year ago.
I have searched the web and found nothing regarding this..
char array[50];
char *array = new char[50];
Tell me the difference between them..
char array[50] is 50*sizeOfChar space allocated on stack.
char *array = new char[50] is 50 * sizeOfChar space allocated on heap, and address of first char is returned.
Memory allocated on stack gets free automatically when scope of variables ends.
Memory allocated using new operator will not free automatically, delete will be needed to be called by developer.
Mixing C/C++ is a nice though sometimes confusing:
char array[50];
Allocation on stack, so you don't need to worry about memory management. Of course you can use std::array<char, 50> array which being C++ brings some advantages (like a method which returns its size). The array exists until you leave its scope.
char *array = new char[50];
Here you need to manage the memory, because it is kept in the heap until you free it. Important, you should use this whenever you want to remove it:
delete [] array;
There also exist free(array) (Standard C) and delete (without parenthesis). Never use those, whenever you use new someType[...].
Other that in both you still have a char array of 50 elements you can play with :-)

Do I have to delete memory in this case?

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);
}

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.

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;
}

Does this generate a memory leak?

void aFunction_2()
{
char* c = new char[10];
c = "abcefgh";
}
Questions:
Will the: c = "abdefgh" be stored in the new char[10]?
If the c = "abcdefgh" is another memory area should I dealloc it?
If I wanted to save info into the char[10] would I use a function like strcpy to put the info into the char[10]?
Yes that is a memory leak.
Yes, you would use strcpy to put a string into an allocated char array.
Since this is C++ code you would do neither one though. You would use std::string.
void aFunction_2()
{
char* c = new char[10]; //OK
c = "abcefgh"; //Error, use strcpy or preferably use std::string
}
1- Will the: c = "abdefgh" be
allocated inner the new char[10]?
no, you are changing the pointer from previously pointing to a memory location of 10 bytes to point to the new constant string causing a memory leak of ten bytes.
2- If the c = "abcdefgh" is another
memory area should I dealloc it?
no, it hasn't been allocated on heap, its in read-only memory
3- If I wanted to save info inner the
char[10] I would use a function like
strcpy to put the info inner the
char[10]?
not sure what you mean with 'inner' here. when you allocate using new the memory is allocated in the heap and in normal circumstances can be accessed from any part of your program if you provide the pointer to the memory block.
Your answer already has been answered multiple times, but I think all answers are missing one important bit (that you did not ask for excplicitly):
While you allocated memory for ten characters and then overwrote the only pointer you have referencing this area of memory, you are created a memory leak that you can not fix anymore. To do it right, you would std::strcpy() the memory from the pre-allocated, pre-initialized constant part of the memory where the content of your string-literal has been stored into your dynamically allocated 10 characters.
And here comes the important part:
When you are done with dealing with these 10 characters, you deallocate them using delete[]. The [] are important here. Everything that you allocate using new x[] has to be deallocated with delete[]. Neither the compiler nor the runtime warn you when use a normal delete instead, so it's important to memorize this rule.
No, that is only pointer reassignment;
No, deleteing something that didn't come from new will often crash; and
Yes, strcpy will do the job… but it's not usually used in C++.
Since nobody has answered with code, std::uninitialized_copy_n (or just std::copy_n, it really doesn't make a difference here) is more C++ than strcpy:
#include <memory>
static char const abcs[] = "abcdefgh"; // define string (static in local scope)
char *c = new char[10]; // allocate
std::copy_n( abcs, sizeof abcs, c ); // initialize (no need for strlen)
// when you're done with c:
delete[] c; // don't forget []
Of course, std::string is what you should use instead:
#include <string>
std::string c( "abcdefgh" ); // does allocate and copy for you
// no need for delete when finished, that is automatic too!
No (pointer reassignment)
No
Yes, you can use strcpy(), see for instance: