I guess my question requires no minmal working example; it's possible a no-brainer and easy to describe.
Let's assume there is a class instance which stores some objects as members. Now one of the members grows during runtime. After creating the instance member1 consumed 10 bytes and member2 20 bytes. Then object1 is modificated somehow and needs now 15 bytes.
My question is if the address of (the first byte of) member1 is unchanged? Or can it potentially be possible that the first byte of member1 has now another address as before?
Are member variables allocated at the heap?
Thanks for your feedback!
Best
Now one of the members grows during runtime.
This scenario is not possible in C++. The size of an object (and the size of a type) is constant at runtime.
member1 has now another address as before?
No. The address of an object will never change through its entire lifetime.
I have a Class instance whose members are from an external library, I don't even know how they internally store the members.
The type of a member variable must be complete. That means that the type must have been defined. If it is defined, then its size and the internal members are known. You have probably included the definition of the type by including a header file. You can read that header to find out the definition.
So this is only possible using heap allocation, is it?
Not necessarily. For example, there could be a pre-allocated buffer that can contain objects up to some constant limit.
But typically yes, dynamic objects use dynamic storage. Based on the observation of increasing memory use, this seems to be the case.
Related
Form the link below Difference between Definition and Declaration says that:
Definition of a variable says where the variable gets stored. i.e.,
memory for the variable is allocated during the definition of the
variable.
And to my knowledge, the declaration of class looks like :
class stu ;
And the definition of class looks like :
class stu{
public:
int x;
};
And so from information above , the memory allocation of this class should happen when I write the complete definition of class.However,
from this link says that :
Memory will be allocated when you create an instance of the class.
which means that the memory woudl be allocated at the moment I write
stu s;
So I would like to know the exact time that memory would allocate for thsi class, in the other word, it happens during compile time or run time?
In general: The memory holding the values for the members is allocated when they are used, which is - with some exceptions - at runtime. (assuming it is not optimized away by the compiler)
The forward declaration of a class is for the compiler to make the type known.
The definition describes the class:
its member functions are transformed into machine code. Those - depending on the target architecture - exist in a data section that is loaded into memory. So the member function takes up memory before any instance is created.
The compiler also stores some information about the memory layout, which is either part of the machine code or also exists somewhere in a data section.
This memory allocation is however about the description of the class, and not what is generally referred to when you talk about memory allocation for a type.
The memory holding the values for the members is allocated when they are used which is generally at runtime. Under certain circumstances, the values of an instance of a type can already be determined at compile-time, which might have the result that those also become part of the data section.
Whenever I'm working on scientific projects in C++, sooner or later I find myself calling methods that need to allocate big temporary objects in memory (e.g. vectors/matrices) needed to compute the final result.
My question is then: when should I consider making these temporaries member variables of the class instead? My reasoning is that if they are members already, then there is no need to allocate new memory every time a method is called that needs to access them to store temporary data. At the same time though, the more memory I allocate for "big" member variables, the harder it might be to find suitable chunks of memory for performing other tasks.
I know that in general member variables should represent some sort of property associated to a class, but memory-wise it seems advantageous to create more member variables at first glance.
Of course this is assuming that pointers or references are already being used where the address of a variable can be used.
I wasn't able to find any clear answer. I hope this is clear, please ask for any clarification if needed.
I understand that with a union, all members share the same memory. With a struct, they do not share memory, so a different space in memory is allocated to each member of the struct.
My solution requires me to create a struct that will only store value in one of the types stored in the struct; behave like a union. The reason why I cannot use a union is because one of the "types" specified is a string and you cannot contain a string variable in a union. How can I ensure only one member of a struct takes up space in the memory at a time?
You'll need a buffer (of size max(sizeof(T1), sizeof(T2), sizeof(T3)...)), placement new, and a enum variable to remember which object is currently in the buffer. It's called a "tagged union". Then you'll need to write member functions to safely control the lifetime of this artifially-inseminated object. Finally, you'll want to spend a few days untangling any alignment requirements.
But this is what boost::variant does so just use that. It'll be std::variant soon, too.
How can I ensure only one member of a struct takes up space in the memory at a time?
You can use a std::any, or std::variant, if supported by your compiler (C++17) or you can template your type
template <typename T>
struct wrap
{
T elem;
};
You cannot. A struct is always the same size. When you create a struct, the compiler reserves space for each member variable in the struct and defines that as the struct's size. When your code asks the memory manager to allocate memory for the struct, it will always allocate the same amount of memory, regardless of whether all of the variables are used or not.
Your best bet is to convert your string to another type that can be used in a union, such as a fixed-size array of chars.
Ok, so I'm very new at C++ programming, and I've been looking around for a couple days for a decisive answer for this. WHEN should I declare member variables on the heap vs. the stack? Most of the answers that I've found have dealt with other issues, but I want to know when it is best to use the heap for member variables and why it is better to heap the members instead of stacking them.
There are two important concepts to grasp first:
One should avoid thinking in terms of "heap" and "stack". Those are implementation details of your compiler/platform, not of the language.1 Instead, think in terms of object lifetimes: should the object's lifetime correspond to that of its "parent", or should it outlive it? If you need the latter, then you'll need to use new (directly or indirectly) to dynamically allocate an object.
Member variables always have the same lifetime as their parent. The member variable may be a pointer, and the object it points to may well have an independent lifetime. But the pointed-to object is not a member variable.
However, there is no general answer to your question. Crudely speaking, don't dynamically allocate unless there is a good reason to. As I hinted above, these reasons usually correspond to situations where the lifetime needs to differ from its "parent".
1. Indeed, the C++ standard doesn't really talk about "heap" and "stack". They're important to consider when optimising or generally thinking about performance, but they're mostly irrelevant from a program-functionality point of view.
Member variables are members of the class itself. They are neither on
the heap nor on the stack, or rather, they are where ever the class
itself is.
There are very few reasons to add a level of indirection, and allocate a
member separately on the heap: polymorphism (if the type of the member
is not always the same) is by far the most common.
To get some terminology straight: What you call a heap and stack describe the lifetime of objects. The first means that the lifetime is dynamic, the second automatic and the third (which you don't mention) is static.
Usually you will need dynamic lifetime of an object when it should outlive the scope it was created in. Another common case is when you want it to be shared across different parent objects. Also, dynamic lifetime is also necessary when you work with a design that is heavyly object-oriented (uses a lot of polymorphism, doesn't use values), e.g. Qt.
An idiom that requires dynamic lifetimes is the pimpl-idiom.
Most generic-programming libraries are more focused towards value and value-semantics, so you won't use dynamic binding that much and automatic lifetimes become a lot more common.
There are also some examples where dynamic allocation is required for more implementation specific reasons:
dynamically sized objects (containers)
handling incomplete types (see pimpl-idiom)
easy nullability of a type
All of those are just general guidelines and it has to be decided on a case by case basis. In general, prefer automatic objects over dynamic ones.
The stack refers to the call stack. Function calls, return addresses, parameters, and local variables are kept on the call stack. You use stack memory whenever you pass a parameter or create a local variable. The stack has only temporary storage. Once the current function goes out of scope, you no longer have access to any variables for parameters.
The heap is a large pool of memory used for dynamic allocation. When you use the new operator to allocate memory, this memory is assigned from the heap. You want to allocate heap memory when you are creating objects that you don't want to lose after the current function terminates (loses scope). Objects are stored in the heap until the space is deallocated with delete or free().
Consider this example:
You implement a linked list which has a field member head of class node.
Each node has a field member next. If this member of the type Node and not Node* the size of every Node would depend on the number of the nodes after it in the chain.
For example, if you have 100 nodes in your list your head member will be huge. Because it holds the next node inside itself so it needs to have enough size to hold it and next holds the next and so on. So the head has to have enough space to hold in it 99 nodes the next 98 and so on...
You want to avoid that so in this case it's better to have pointer to to next node in each Node rather than the next node itself.
I'm aware that questions about the stack vs. the heap have been asked several times, but I'm confused about one small aspect of choosing how to declare objects in C++.
I understand that the heap--accessed with the "new" operator--is used for dynamic memory allocation. According to an answer to another question on Stack Overflow, "the heap is for storage of data where the lifetime of the storage cannot be determined ahead of time". The stack is faster than the heap, and seems to be used for variables of local scope, i.e., the variables are automatically deleted when the relevant section of code is completed. The stack also has a relatively limited amount of available space.
In my case, I know prior to runtime that I will need an array of pointers to exactly 500 objects of a particular class, and I know I will need to store the pointers and the objects throughout the duration of runtime. The heap doesn't make sense because I know beforehand how long I will need the memory and I know exactly how man objects I will need. The stack also doesn't make sense if it is limited in scope; plus, I don't know if it can actually hold all of my objects/pointers.
What would be the best way to approach this situation and why? Thanks!
Objects allocated on the stack in main() have a lifetime of the entire run of the program, so that's an option. An array of 500 pointers is either 2000 or 4000 bytes depending on whether your pointers are 32 or 64 bits wide -- if you were programming in an environment whose stack limit was that small, you would know it (such environments do exist: for instance, kernel mode stacks are often 8192 bytes or smaller in total) so I wouldn't hesitate to put the array there.
Depending on how big your objects are, it might also be reasonable to put them on the stack -- the typical stack limit in user space nowadays is order of 8 megabytes, which is not so large that you can totally ignore it, but is not peanuts, either.
If they are too big for the stack, I would seriously consider making a global variable that was an array of the objects themselves. The major downside of this is you can't control precisely when they are initialized. If the objects have nontrivial constructors this is very likely to be a problem. An alternative is to allocate storage for the objects as a global variable, initialize them at the appropriate point within main using placement new, and explicitly call their destructors on the way out. This requires care in the presence of exceptions; I'd write a one-off RAII class that encapsulated the job.
It is not a matter of stack or heap (which to be accurate do not mean what you think in c++: they are just data structures like vector, set or queue). It is a matter of storage duration.
You most likely need here static duration objects, which can be either global, or members of a class. Automatic variables declared inside the main function could also do the job, if you design a way to access them from your other code.
There is some information about the different storage durations of C++ (automatic, static, dynamic) there. The accepted answer however uses the confusing stack/heap terminology, but the explanation is correct.
the heap is for storage of data where the lifetime of the storage cannot be determined ahead of time
While that is correct, it's also incomplete.
The stack unwinds when you exit its scope, so using it for global scoped variables is unfeasible, like you said. This however is where you stop being on the right track. While you know the lifetime (or more accurately the scope since that's the most important factor here), you also know it's above the stack frame, so given only two choices, you put it on the heap.
There is a third option, an actual static variable declared at the top scope, but this will only work if your objects have default constructors.
TL;DR: use global (static) storage for either a pointer to the array (dynamic allocation) or just the actual array (static allocation).
Note: Your assumption that the stack is somehow "faster" than the heap is wrong, they're both backed in the same RAM, you just access it relative to different registers. Also I'd like to mention yet again how much I dislike the use of the terms stack and heap.
The stack, as you mention, often has size limits. That leaves you with two choices - dynamically allocate your objects, or make them global. The time cost to allocate all of your objects once at application startup is almost certainly not of significant concern. So just pick whichever method you prefer and do it.
I think you are confusing the use of the stack (storage for local variables and parameters) and unscoped data (static class variables and data allocated via new or malloc). One appropriate solution based on your description would be a static class that has your array of pointers declared as a static class member. This would be allocated on a heap like structure (maybe even the heap depending on your C++ implementation). a "quick and dirty" solution would be to declare the array as a static variable (basically a global variable), however it isn't the best approach from a maintainability perspective.
The best concept to go by is "Use the stack when you can and the heap when you must." I don't see why the stack wouldn't be able to hold all of your objects unless they're large or you're working with a limited resources system. Try the stack and if it can't handle it, the time it would take to allocate the memory on the heap can all be done early in the program's execution and wouldn't be a significant problem.
Unless speed is an issue or you can't afford the overhead, you should stick the objects in a std::vector. If copy semantics aren't defined for the objects, you should use a std::vector of std::shared_ptrs.