This question already has answers here:
Is it required to check a pointer validity if new fails?
(4 answers)
Closed 4 years ago.
I don't know a lot about C or C++ but I think with C when you create an array you use malloc to ask for the memory and then you check that the memory was allocated before assigning values. In C++ you implement an array using new instead. Would check the allocation of memory for the array in C++ the same as in C by checking that the array is not null?
For example,
int main()
{
int* myArr = new int[10];
if(myArr!=NULL)
{
//DO SOMETHING
}
}
I get that most computers have a lot of memory, making running out of memory less likely today, but I also understand that failing to do things like this can lead to unexpected bugs later on down the road.
UPDATE: I was trying to keep my example simple. As mentioned in the comments I was referring to dynamic memory allocation. I am trying to implement a heap data structure. As part of the heap there exists an array to store the values of the heap. When the heap is full the array has to be expanded by design by the next power of 2. Thus i may initialize the heap as 10 but when I reach 10 I will need to expand to 16. Given enough items the heap will reach size 2^n. Therefore I am calling a function that has a parameter for the HEAP pointer. Then I create a new array and copy the values from the existing array to the new array. While doing this I was thinking about what happens if the new array cannot be created because of being out of memory. I may want to write the values to a file before exiting.
No, to make an array you do this:
int main()
{
int myArr[10];
// DO SOMETHING
}
If you must use dynamic allocation, use new without the std::nothrow specifier, so that it throws a std::bad_alloc exception if the allocation fails. That is ultimately the equivalent of checking for malloc returning a NULL pointer.
If you do use the std::nothrow specifier then, yes, check for a NULL pointer. In modern C++, that's nullptr. In antique C++, that's NULL (or 0) as you've shown.
Related
This question already has an answer here:
allocating space to list<int> pointers using malloc not working
(1 answer)
Closed 5 years ago.
I want to create array of list which can store list. so i use malloc and get the storage.
list<int>*adj;
adj = (list<int>*)malloc(sizeof(list<int>)*v);
adj[0].push_back(1); ==> crash occure in this line...
But when is use new operator then it works fine..
list<int> *adj;
adj = new list<int>[v];
adj[0].push_back(1); ==> works fine
Can somebody help why malloc is not working ?
Main difference btw allocating memory by malloc() and operator new - malloc() would not call constructor and so your object is not initialized properly. You should not use malloc() to create c++ objects unless you have real reason, if you do have one use placement new to initialize object properly.
malloc only returns a pointer to bytes of uninitialized memory it allocated. That means that you do not actually have a std::list object (nothing ever constructed one since malloc has no notion of such concepts), but merely a pointer to enough bytes of memory to store a std::list object in.
This is different to the line with new: new allocates enough memory for a std::list object and then actually constructs one in this memory. After this construction, you can use the std::list, and this construction is required for std::list to work!
You should not use malloc in C++, at least I do not know a single valid usecase for it.
malloc is C function. It ONLY allocates sizeof memory. You should use new operator, which will also call list constructor.
Probably list constructor also calls new to allocate some internal data, without calling it you have pointer to corrupted structure.
This question already has answers here:
Is delete[] equal to delete?
(6 answers)
how to properly delete a pointer to array
(6 answers)
How do I use arrays in C++?
(5 answers)
dynamically allocated string arrays failed to be deallocated
(2 answers)
Closed 9 years ago.
int* arr = new int[count];
delete arr;
Why does this work? I've checked and it actually frees the memory. From what I've read I need delete[] arr; otherwise it won't actually free all the memory.
The difference is not whether or not the allocated memory is properly freed - whether you use
delete
or
delete[]
the memory will still be properly deallocated.
The difference is whether or not the destructors will be properly invoked.
delete // will only invoke the destructor of the first element of the array.
delete[] // will invoke the destructor for *each* element of the array.
This has no practical effect for primitive types like int or float, but when you have an array of some class, the difference can be critical.
Now try it with filling the array with strings of 100 bytes each, and see if it still frees all the allocated memory...
It is undefined behaviour, and as always, sometimes UB will appear to work. In your case, you have no destructor for the objects in the memory, so there is no "further work", just free all the memory [1]. But if you have an object that has a destructor that does something useful, it (probably) won't get called.
You should ALWAYS use delete [] if you used new T[size]; to allocate. Don't mix the two, it's always wrong - just sometimes it HAPPENS to work [just like SOME sizes of spanners in inches works on mm nuts and vice versa - but it's still wrong to use a inches spanner set on metric nuts].
[1] Note that this may work for this particular compiler/C++ library combination. Compiling it with a different compiler, using a different C++ library, or compiling for a different OS may cause it to crash when you try the same thing.
delete and delete [] are actually different operators and to use the wrong one is always an error. The problem is that it often seems fine at the time, but the heap has ben corrupted and you are very likely to experience an apparently unrelated crash later.
This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 9 years ago.
Is there a function (that could be written) which allows to know the size of an array defined with new:
int *a=new int[3];
*a=4;
*(a+1)=5;
*(a+2)=6;
Thanks!
There is not a standard way get the size of an array allocated with new.
A better approach to array allocation is std::vector, which does have a size() member -- and it automatically cleans up after itself when it goes out of scope.
Short answer: No.
Use std::vector instead.
It would be possible to write a function for this. But in the real world, it's a poor idea.
Although the act of calling new most likely stores the number of elements in the array that is allocated (or at least, the size of the actual allocation underneath it), there is no way that you can get that information in a way that doesn't rely on knowing how new works on your particular system, and that could change if you compile your code differently (e.g. debug or release version of the code), change version of the compiler (or runtime library), etc, etc.
Using the std::vector as mentioned is a much better way, since you then ALSO don't have to worry about freeing your array somewhere else.
If, for some reason, you don't want to [or have been told by your tutor, that you can't] use std::vector, you need to "remember" the size of the allocation.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why [] is used in delete ( delete [] ) to free dynamically allocated array?
Why does C++ still have a delete[] AND a delete operator?
I'm wondering what's their difference and I know the obvious answer some might say, that one is to delete an array and the other is to delete a single object but I'm wondering why should there be two different deletion methods for these two operations? I mean delete is basically implemented using C free method which doesn't care if the pointer is actually pointing toward an array or a single object. The only reason I can think of is two be able to know if it's an array and call destructor for each cell instead of only the first object but that wouldn't also be possible since compiler can not guess the length of array just looking at it's pointer. By the way though it's said to invoke undefined behavior to call delete for memory allocated with new[] I can't imagine anything that could possibly go wrong.
As you have discovered the compiler needs to know the length of an array (at least for non-trivial types) to be able to call destructors for each element. For this new[] typically allocates some extra bytes to record the element count and returns a pointer to the end of this bookkeeping area.
When you use delete[] the compiler will look at the memory before the array to find the count and adjust the pointer, so that the originally allocated block is freed.
If you use delete to destroy a dynamically allocated array, destructors for elements (except the first) won't be called and typically this will end up attempting to free a pointer that doesn't point to the beginning of an allocated block, which may corrupt the heap.
but that wouldn't also be possible since compiler can not guess the
length of array just looking at it's pointer
That's not really true. The compiler itself doesn't need to guess anything, but it does decide which function to call to free the memory based on the operator it sees. There is a separate function dedicated to releasing arrays, and this function does indeed know the length of the array to be freed so it can appropriately call destructors.
It knows the length of the array because typically new[] allocates memory that includes the array length (since this is known on allocation) and returns a pointer to just the "usable" memory allocated. When delete[] is called it knows how to access this memory based on the pointer to the usable part of the array that was given.
When you allocate memory using new[], the compiler not only needs to construct each element, it also needs to keep track of how many elements have been allocated. This is needed for delete[] to work correctly.
Since new and delete operate on scalars, they don't need to do that, and could save on a little bit of overhead.
There is absolutely no requirement for new to be compatible with delete[] and vice versa. Mixing the two is undefined behaviour.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Differences between dynamic memory and “ordinary” memory
I was reading the C++ tutorial and I don't understand why I need to declare dynamic memory, this is what the tutorial says:
Until now, in all our programs, we have only had as much memory available as we declared for our variables, having the size of all of them to be determined in the source code, before the execution of the program.
And then it says that we have to use new and delete operators to use dynamic memory.
However, I seem to be using dynamic memory when declare a pointer, e.g. char* p, for which I have not specified the length of the array of characters. In fact, I thought that when you use a pointer you are always using dynamic memory. Isn't it true?
I just don't see the difference between declaring a variable using new operator and not. I don't really understand what dynamic memory is. Can anyone explain me this?
I thought that when you use a pointer you are always using dynamic
memory. Isn't it true?
No it's not true, for example
int i;
int *p = &i; // uses a pointer to static memory, no dynamic memory.
However, I seem to be using dynamic memory when declare a pointer,
e.g. char* p, for which I have not specified the length of the array
of characters
char[100] string;
char* p = &(string[0]); // Same as above, no dynamic memory.
You need dynamic memory when you can't tell how big the data structure needs to be.
Say you've to read some ints from a file and store them in memory. You have no idea how many ints you need. You could pick a figure of 100, but then your program breaks if there are 101. You could pick 100,000 hoping that's enough, but it's waste of resources if there's only 10 in the file, and again, it breaks if there's 100,001 ints in the file.
In this scenario your program could iterate through the file, count the number of ints, then dynamically create an array of the correct size. Then you pass over the file a second time reading the ints into your new array.
Static v's Dynamic Memory
Static memory is static because once the program is compiled it can't be changed, it is static. Variables you declare in functions, and members declared on classes / structs are static. The compiler calculates exactly how many of each its going to need as each method gets called.
Dynamic memory is a "pool" of memory that can be made available to your program on demand, at run time.
The compiler only knows it needs to allocate some (probably unknown) amount of that memory, and to release that memory back to the dynamic memory pool.
Hope this helps.
P.S. Yes, there are more efficient ways to get an unknown number of items into memory, but this is the simplest to explain
When you have:
char* p;
p is variable of type pointer to char and p is stored on the stack and you haven't allocated any dynamic memory.
But when you do:
p = new char[100];
you have allocated a part of dynamic memory (heap) of the size 100*sizeof(char).
You are responsible to free allocated memory on the heap:
delete[] p;
You don't need to clean variables from the stack - they will be removed automatically after variable goes out of scope. In this example, p will be removed from the stack when it goes out of its scope.
Dynamic memory is memory which the programmer has to explicity request, as an oppose to have automatically allocated on the stack.
There are many advantages to dynamic memory such being persistent between stack frames (function calls) and can be of varying size.
On the stack an array much be of a certain size:
int ar[5];
However if you 10 element then you can't do it, the solution is to dynamically allocate the memory;
size_t sz;
std::cin >> sz;
int *i_p=new int[sz];
That said everything dynamically allocated must be freed (in C++ using delete)
delete i_p;
However it is generally better where possible to use wrappers to dynamic arrays such as the std::vector
size_t sz;
std::cin >> sz;
std::vector<int> vect(sz);
This will automatically manage the memory and provide a useful interface to the array.
Let's say you want to read an unknown number of integers from a user. You could, for example, declare int numbers[100], ask the user how many numbers there are (let's say this is store in variable n) and if he enters a number larger than 100, you would have no choice but to report an error. Alternatively, you could write int *numbers = new int[n] and allocate just enough space for all the numbers.
Dynamic memory in c++ is a memory allocated in a heap of operation system by using new operator. You need the dynamic memory when you need to allocate the objects which are too large and cannot be allocated in the stack, or when you have a multithreaded environment and need to share the memory allocated in one of the threads between the different threads. Pointer doesn't mean that you use the dynamic memory pointers also can contain the a stack address related with the object in the stack.
In fact, I thought that when you use a pointer you are always using dynamic memory. Isn't it true?
No. Here's a pointer to stack-allocated ("automatic") memory:
{
int i;
int *p = &i;
}