char * a = new char[];
a[0]='1';
delete []a;
I didn't specify the size of the array, but when I ran it, it gave a debug error. But when I write this code as follow:
char * a = new char[1];
a[0]='1';
delete []a;
then it will be OK.
Can any body tell me why it will run correctly when I specify a number?
char * a = new char[];
doesn't allocates any memory. Its not even a valid statement and should result in an error or warning atleast.
char * a = new char[1];
does for a single character and that's why you can use and delete it. The new keyword requires the amount of memory to be allocated.
When using the new keyword you indicate how much memory you want to reserve.
For example, when you say char *a = new char[1]; you are saying that you need an array that can hold 1 character.
In the first statement that you posted, you are not reserving any memory and that is why your program is crashing.
char * a = new char[];
You should tell how much memory to be allocated, which should be done within []
However for delete you don't need to tell the size of the array, the run-time system knows the size of the array pointed by the pointer a
delete []a;
But don't forget to put [] for deleting the an array.
Related
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 :-)
Because segmentation fault related to malloc/free happens, I would like to convert malloc/free to new/delete.
Error occurred when malloc/free is converted to below.
Let me know how to solve it.
(original)
char *only_valid_data = static_cast<char*> (malloc (data_size));
(converted)
char *only_valid_data = new static_cast<char*> [data_size];
Just do
char* only_valid_data = new char[data_size];
to allocate.
To free you do
delete[] only_valid_data;
Important note: When you allocate memory with new it will allocate data_size elements, not data_size bytes (like malloc does). The size of an element is the size of the non-pointer base type, in your case e.g. sizeof(*only_valid_data). In this case the element size and the byte size is the same (as sizeof(char) is specified to always be 1), but if the base type is something else it will make a big difference.
For example, if you do
int* int_ptr = new int[10];
then ten integers will be allocated, not ten bytes. This is equivalent to
int* int_ptr = reinterpret_cast<int*>(malloc(10 * sizeof(*int_ptr)));
Also note that for complex types, like structures and classes, allocating with new (or new[]) does more than just allocating memory, it will also make sure that the allocated object(s) constructor is called. The malloc function only allocates memory, it doesn't call the constructor.
Final note: The problem you have with the segmentation fault is probably not caused by your allocation, no matter how you allocate the memory. The problem is more likely because of something else, something you do not show in your question, like writing out of bounds of the allocated memory or dereferencing a null-pointer.
You need run your program in a debugger to catch the crash in action, it will allow you to examine the function call stack, and if the crash doesn't happen in your code then you walk up the call stack until you reach your code. There you can examine the values of variables, to help you understand why the problem occurred.
The malloc family (malloc, realloc, calloc, free) is used almost always in C code, as C++ provides the new and delete operators which are a lot more reliable to use.
A problem with malloc for allocation is that you must specify the size of the type in bytes that you want to allocate. For example:
int* ptr = malloc(5);
Will not allocate space for 5 integers in memory; it will allocate 5 bytes of memory (the size of an integer is 4 bytes, so this would obviously cause problems when assigning).
To do it properly, it must be written as
int* ptr = malloc(5 * sizeof(int));
So that 20 bytes are allocated.
However, there are some exceptions to the case. char, for example only requires one byte of memory, so doing
char* ptr = malloc(5);
Will allocate enough memory to hold 5 characters, and in a way is more valid that writing:
char* ptr = malloc(5 * sizeof(char)); //5 * sizeof(char) == 5 * 1 == 5
However, the free function does not need to know the size of the pointer to be deallocated; a void* is only needed.
Note that in C++, the return of malloc must be cast properly to the type wanted; malloc returns a void* type, but C++ does not allow any pointer to assign a void* to any pointer type like C does:
int* ptr = malloc(5 * sizeof(int)); //valid C code, invalid C++
int* ptr2 = (int*)malloc(5 * sizeof(int)); //valid C code, valid C++
In C++, the new[] operator resolves the issue of remembering to add the sizeof operator.
int* ptr = new int[5];//allocates 5 integers
int* ptr2 = new int(5);//be careful: this allocates a single integer with value of 5
Note that if the new[] operator has been used, the delete[] operator must be used. Otherwise the delete operator must be used:
int* ptr = new int[5];//allocates 5 integers
delete[] ptr;//deallocate the 5 integers
int* ptr2 = new int(5);//be careful: this allocates a single integer with value of 5
delete ptr;//deallocate the integer
The problem with your code is that it does not fit the syntax of the new[] operator
The syntax could be described as:
T* p = new T[size];
Thus your code:
char *only_valid_data = new static_cast<char*> [data_size];
Should be corrected to:
char *only_valid_data = new char[data_size];
As static_cast<char*> is not a type.
Hope this helps :)
I have a piece of code:
#include<iostream>
using namespace std;
int main()
{
char * str = new char;
cin >> str;
cout << str;
delete str;
}
vs.
#include<iostream>
using namespace std;
int main()
{
char * str = new char[30];
cin >> str;
cout << str;
delete []str;
}
When I give input to either program using STDIN, which program ensures that there are no memory leaks?
This doubt arose as our professor told us that a char * is basically equivalent to an array of chars only. So if I allocate heap memory as in the first case and let str 'hold' an array of chars, if I then delete str, does it delete the array completely? I know that the second case manages to do so.
I have already been through ->
delete vs delete[] operators in C++
delete vs delete[]
And thus I know that delete[] deletes memory allocated by new[] and delete does the same for new. But what if new itself allocates contiguous memory locations??
Your both first code example is wrong.
char * str = new char;
cin >> str;
You've only allocated memory for a single character. If you read anything other than an empty string, you'll write into unallocated memory and will have undefined behaviour.
if I then delete str, does it delete the array completely?
It will only delete the one character that you allocated. The rest of the string that you wrote in unallocated memory won't be directly affected by the delete. It's not a memory leak, it's a memory corruption.
vs.
char * str = new char[];
This is not legal c++. Array size must be specified.
EDIT: After your fix, the second code is correct as long as you read a string of 29 characters or shorter. If you read a longer string, you'll get undefined behaviour again.
But what if new itself allocates contiguous memory locations?
It doesn't. new (as opposed to new[]) allocates and constructs exactly one object. And delete destroys and deallocates exactly one object.
TLDR Neither program has memory leaks but the first one has undefined behaviour due to memory corruption.
I believe that you are misunderstanding what the difference is between a memory leak and a buffer overflow.
What is a buffer overflow?
A buffer overflow occurs when we have some piece of memory that we are going to store some data in. And when we store that data, we put too much data there. For example:
int x[4];
x[0] = 7;
x[1] = 8;
x[2] = 9;
x[3] = 10;
x[4] = 11; // <-- Buffer Overflow!
Your code exhibits a potential buffer overflow because cin doesn't know how much memory you've allocated. And there's no real method to tell it that when using char * arguments. So in your first example, if you were to write any string longer than the empty string, you would cause a buffer overflow. Likewise, if you were to write more than 30 characters (including the null character) to the second example, you would also cause a buffer overflow.
What is a memory leak?
A memory leak is traditionally represented this way:
char *x = new char[30];
x[0] = 'a';
x[1] = '\0';
x = new char[10]; // <-- Memory Leak!
At this point in the code, you have no ability to call delete[] on the first allocation. You have no variable that points to that pointer. That is a memory leak.
What does delete[] do?
Let's consider that there is some bucket somewhere that can give us chunks of memory. We can grab chunks of memory from that bucket via new and new[]. When we use delete and delete[], we return those chunks of memory back to the bucket.
The agreement that we make with new and delete is that once we call delete on a piece of memory, we don't continue to use it. We don't do this, because the system may reuse that piece of memory, or it may have removed all ability to access that pointer all together.
How could this possibly work?
You have this piece of code:
char *x = new char;
cin >> x;
I'd like to tell you that it's basically the same as this piece of code:
char y;
cin >> &y;
In both cases, you've allocated space for only one char. So when we call delete on x, we're only deleteing one char. The part of the code there that will likely break is that cin will think that there is enough memory allocated for whatever string it is going to try and write to that pointer.
The fact is, there probably isn't enough space. There's only space for one char. And even the string "a", takes up 2 chars.
You can't do such things.
char *ptr = new char;
means that you have allocated sizeof(char) bytes.
If you will execute cin >> ptr, and pass there more than 1 character, you will get segfault as the memory isn`t allocated.
To allocate an array of chars you need to do it in next way:
char *ptr = new char[ size ];
It will allocate size * sizeof(char) bytes.
And then you can use cin >> ptr to fill it with data.
I've been trying to deallocate this array of char pointers, but I'm not sure how to fully deallocate it.
Here's the code:
char* words[4];
words[0] = new char[8];
words[1] = new char[6];
words[2] = new char[10];
words[3] = new char[16];
and heres what i tried
for (int i=0;i<4;i++)
{
delete [] words[i];// this works
}
delete [] words;//this gives an error, not sure why it doesn't work.
Can somebody please explain why this isn't correct and how to fix it
thanks in advance.
Only delete what you new. You didn't new words, so don't delete it. Presumably this code is inside a function, in which case words has automatic storage duration and will be destroyed automatically when it goes out of scope.
Moreover, don't new anything you don't have to, to save yourself the hassle of deleting it correctly (which can be surprisingly difficult). Use std::vector when you want a dynamic array, and std::string when you want a dynamic string.
It is not correct because words is not itself dynamically allocated like the pointers it contains.
words is on stack, words[i] is on heap. As a general principle you need a delete[] for each new[]. You have 4 new and you need 4 delete.
char *words[4] // on stack, doesn't need deallocation
char **words = new char*[4]; // on heap, would need deallocation too
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: