Coming from c, I would use dynamic allocation if i wanted a variable to outlive the scope of the array, prevent things like dangling pointers, and creating arrays with a size that isnt know during run time. In C++ i learned, there is no reason to dynamically allocate an array because in that case you would just use a vector, other than having things outlive the scope, is there any other use for dynamic allocation in c++?
#Purpose of dynamically allocating things
1 messages · Page 1 of 1 (latest)
When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.
dynamic allocation is useful for smart pointers and creating new containers... other than that personally i would avoid dynamically allocating memory
if you want something to exist beyond a scope that's still possible through smart pointers, and even than since those objects can be destroyed when out of scope it makes managing that dynamically allocated memory much much easier
and less error prone
The stack is not infinite, to put it very simply.
I mean the heap isnt infinite either 🤷♂️
it’s bigger tho
Sure its bigger but that isnt the only property that distinguishes the two
Any resource that does not fall into the category of automatic storage duration should be allocated dynamically
Where did you get the "use vector instead of dynamic allocation"? It's true vectors provide a convenient way of dealing with dynamic arrays, and even allowing the size to change with automatic reallocations, but it's far from a universal solution. Also to keep in kind, even though vectors use dynamic allocation in the backend, the vector itself is still on the stack by default and needs to remain in scope, otherwise its allocation is also deleted. So you neither can't just pass around a vector pointer or a value, as passing the value will copy all items in most cases.
a vector just manages a dynamically allocated array
struct vector{
/* bunch of member functions */
private:
T* data;
size_t siz;
size_t cap;
};
this is esentially what a vector is.
Creating new containers? I thought that in c++ it has copy semantics so you essentially can just return vectors and arrays by value
Someone in this discord told me that, and that the data member of a vector is already on the heap so there’s no point in dynamically allocate a vector
So would there be cases where I need to dynamically allocate a std::array or std::vector then
Doesn’t make_unique handle that, so that way I don’t have to use new
do you think those are magic stuff?
"copy semantics" is just a constructor call that copies the array element by element
//disregard capacity for now
vector::vector(const vector& other) : data(new T[other.siz]), siz(other.siz) {
std::copy(other.data, other.data+other.siz, data);
}
this is just how vector is copied
there is no magic
its the same as C
Sorry I meant move semantics
just abstracted away so you dont see
The point of putting stuff on the heap is to be able to change how many bytes you have allocated for an address, and as well as having a life time not tied to stack
move semantics arent magic either
you can implement your own containers 
Vector handles that and you can handle its lifetime in a manner less error prone
When I went over learncpp it said that the move semantics for vectors are actually not expensive so we can just return them
Wdym as in own contained
yes its just reassigning a pointer
Not unless you copy tje wjole tjing
as in you write your own vector
There are containers other than vector
Like maps, stacks etc
Oh okay yeah
Wdym by this?
you asked what the purpose of dynamic allocation is
Copying the entire vector is expensive
the purpose is that you wouldnt have vector and other stuff like it without dynamic allocation
You are copying its entire contents if you pass it by value to a function if i remember correctly
But it’s all abstracted away in Cpp, so the only time I’d use it is if I were to make my own container then?
irrelevant in this conversation tho...
yes
Oh sorry I meant move semantics
Irrelevant
Doesnt matter much for dynamic allocation.
Idk man i dont use move sementics 😭😭😭
you still use them and if you dont have them you cant have the abstractions either
Use them for what?
but I was asking about manually allocating things
i genuinely dont understand the point of the thread tbf
A vector hides the dynamic allocation part
every language that wants to do anything significant needs some kind of dynamic allocation
Hes asking som bout manually allocating things vs using containers to do it for u
yes? so 
thats why you should use it over making your own
Yes so I was just asking about what case would I have to manually allocate stuff
oh
If things like vectors already handle it
hopefully never!
Unlike in c where you have to manually allocate arrays since you don’t have things like vectors
i mean if you consider std::make_unique a dynamic allocation then there is that
Like i said bud, you ideally dont have to unless you are making your own containers 🥺🥺🥺
sometimes you do dynamic allocation but you handle it through smart pointers instead of owning raw pointers
it has to do with RAII, making resource management automatic
Or like making smart pointers, which require an address on heap/ given by new
Sometimes
no point in writing a lot of abstractions in C because you still have to manually reallocate, allocate, free the array
Would be used for polymorphism as well? Or do you not need to use new for polymorphism
Real
c++ gives you destructors which is a C programer's wet dream
smart pointers can take care of that too ^^
Nope. Vector can take the base class
well not really, vector<Base> cant store a Derived object
Has to be a pointer to the base class no?
yes.
unique_ptr<Base>
Beat me to it
:)
So what, vector<unique_ptr<base>>
and there you just solved the whole problem of "delete on remove" and stuff like that 
yes.
So I would have to just give it a pointer to the derived object?
Ok
Doesn’t matter if it’s on stack or heap?
unique_ptr manages a pointer that points to dynamically allocated stuff
Depends on the type ig
For vector
base* can be stack and heap
But required your own management of it
its basically
class unique_ptr{
T* ptr;
public:
unique_ptr(T* ptr) : ptr(ptr) {}
~unique_ptr(){
delete ptr;
}
};
Essentially becomes a shitier smart pointers atp prob
dont initialize a unique_ptr with a pointer to an automatic lifetime variable 👍
So once unique ptr goes out of scope or is deleted its feed
that will cause a use after free bug
int x = 5;
std::unique_ptr<int> ptr(&x);
//ptr destructor calls delete &x;
//x is "freed" again due to it being an automatic lifetime variable
How would I use unique ptr for this? Just learned about it, whenever I see poly morphism examples they either just use a reference or a pointer ie.
Base& x{derived}
//or
Base* x{&derived}
Idk maybe there is a wrapper for unique pointers that works with both stack/heap
Second prob works first no?
std::unique_ptr<Base> = std::make_unique<Derived>();
Can’t you just do make_unique?
Oh lol
yes that would be the correct way
real
Both would work no?
Oh did not know that
When I first learned about polymorphism people just used new, so they’d do:
Base* x = new Derived;
So it just made me wonder whether or not poly morphism needs to work with dynamically allocated memory or not
It doesnt
Like if it would break somewhere down the line if I used it with an automatically managed object
Oh
a pointer is a pointer doesnt matter if its heap or stack
What changes is its lifetime and how much is allocated for that address
even than… the amount allocated for the address is stored at compile time per address for stack… the program just knows which address+ offset is for which variable… the heap is programatic unlike stack
but thats a bit advanced.. only useful in assembly land where you manually have to subtract anf increment the stack and manually remember which offset at rsp is for which variable
Its thr fact that you have to read addresses + offsets at the top of rsp register (which is stack) that makes it so rigid. Maybe you should learn more about stack frames and how stack is allocated and maintained in assembly/C, it could be informative to you
Programming is amazing. Computers allow us to do things that otherwise would be impossible. But sometimes, the code that we write feels like MAGIC. How does all of this stuff work?
Let's talk about how stacks work.
🏫 COURSES 🏫 Check out my new courses at https://lowlevel.academy
📰 NEWSLETTER 📰 Sign up for our newsletter at https://...
Pretty good video.. always seek the knowledge 🥴🥴🥴
Oh yeah idk why I got confused lol. I’ve been transitioning to c++ from c and classes just trip me up and C++ making things easier just tickles my brain
Just curious since we’re on the topic
One of the lessons on Learn Cpp says that if I have a base and derived, and I dynamically allocate the derived into the base ie. Base *x{new derived}. Then I need to make the base destructor virtual so that the derived constructor is called first then the base but I’m confused because when we do the constructors we don’t make them virtual but it would call the base constructor then the derived. Whys it different?
In the line 'Base* base = new Derived();` you're explicitly calling the derived constructor after allocating it on the heap. However if you store it as a bass class pointer, the compiler is only aware of the destructor for the pointer type, as that's what is fixed at compile-time. By making the destructor a virtual function, you force the call to go through the v-table like any other virtual function. Since you used the Derived constructor, the v-table pointer will also point to Derived, including the address of the Derived destructor
Doesn’t it call the base constructor before the derived constructor?
Yes. However, when you call new Derived() you're explicitly constructing a derived, and then you store that derived in a Base pointer. So when you call the constructor, it knows that you're constructing a Derived and it knows to call the Derived constructor after the Base constructor. Ones its put into the Base* however, it no longer knows that its a Derived, it just knows that you have something that has the same interface as a Base. Thus, any function calls will only go down to the Derived if they're over-writing virtual functions.
Some other notes on this thread generally:
You use dynamic allocation if the size of something isn't known at compile time or if you need to manage the length something exists for. In modern C++, you'll never use raw dynamic allocation, you'll either use smart pointers (Unique/Shared) for managing lifetimes or some STL container (vector, list) for managing size at runtime.
In the case of polymorphism, smart pointers are used if you're not sure what type you're going to be allocating at compile time, so you can generate and store pointers to derived types as a base type at runtime.
Move semantics are complex beast. Essentially, its safe to return a vector from a function as that will avoid a copy, since the returned value is an rvalue and the = operator or constructor will use the move variant, and move the underlying data pointer rather than copying the data. When passing values to functions, you should be using reference for non-primitive types (STL types, custom objects) to avoid copies (IE pass std::string& str instead of std::string str.
For the last part, prefer adding const before type& unless you absolutely need to mutate the object within the function. Not only does that allow passing const objects, but more importantly it allows creation within the call. For instance, you can "Hello World" as a const std::string& but not if the parameter is std::string&
You can return a vector as a result from a global function, the vector will outlive the local vector variable that you have, and keep all of the elements of the vector alive and valid on the heap, the copy constructor of the std::vector<T> class does that
Oh and try to avoid smart pointer magic while learning the basics, cause, they are complicated, you must come prepared with knowledge about the C++ language rules first
Well technically it won't outlive it, there will be a new vector constructed from the old one 🤓
Also when returning a local variable, there will be a move most likely, not a copy
No reason to copy if the local is destroyed afterwards anyways
ye, guaranteed RVO since C++17 I think
Well part of rvo at least yeah
Gcc actually has a warning where it failed to apply rvo which is cool