ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
How can I construct an object at a certain address?
The problem is: I have allocated (enough) memory for an std::vector, and now I want to call an std::vector constructor for this memory address. Is there any way I can do this?
Ya.... if I'm understand your question correctly, the only way to accomplish this is to write a class that overloads the way the constructor for the std::vector works. In the typical situation the standard vector calls the standard allocator on creation and handles the memory for you... that is kind of the point of the STL classes...
Maybe you have a vector of objects, with each vector element being the size to hold an object?
If so that's not the way to go. Create a vector of pointers to the base object and then as you create the objects that you want assign them into the vector. This will work for objects of different classes so long as they share the same common parent, and then polymorphism with kick in for your virtual methods.
You didn't understand my question. I do not want to construct the objects held by the vector, but instead the vector itself, at a certain address.
An example (independent of std::vector):
Code:
class A
{
public:
A( int value ) : x( value ) {}
int x;
}
// ...
A *p = malloc( sizeof( A ) );
// Now call the constructor of A for p
// Something like:
p.constructor( 5 );
// ...
p.destructor();
free( p );
A in this example corresponds to std::vector in my code.
(I have my reasons not to write "p = new A( 5 );" )
I hope I could make my problem clear. Do you have any suggestions?
There is nothing stopping you from having a method called constructor and using it like an initialiser method - remember in C++ the constructor is the name of the class and when called dynamically is used in conjunction with the new keyword.
I should add not using the new keyword is going to provide you with code that is harder for others to maintain, because they will be expecting to use the new keyword.
Second your code needs to dereference the pointer, hence it should be p->constructor(5);
(I have my reasons not to write "p = new A( 5 );" )
can you tell me the reason for the above?
Not using the keywords is bad for reason mentioned and because delete also calls the destructor of classes/templates. If you insist on using malloc and free things get difficult.
using new you would have
Code:
std::vector<type>* new_vector = new std::vector<type>;
translating this to using malloc throws some problems.
There is nothing stopping you from having a method called constructor and using it like an initialiser method
Yes, there is:
1.) Obviously I can't modify std::vector (or, in the example, class A).
2.) If the class contains virtual functions, the virtual-functions-table pointer has to be initialized. This can't be done manually.
Quote:
I should add not using the new keyword is going to provide you with code that is harder for others to maintain, because they will be expecting to use the new keyword.
As I said, there are reasons.
Consider the following situation: you have a class which uses only a very small amount of memory, say 1 byte, and you can't change that class (its declaration and definition are given).
Now, using new will occupy at least 12 bytes on my 32-bit machine (new[] is not an option, for certain reasons). If you create 2^20 instances, 11 MiB will be wasted for just 1 MiB payload. This is hardly acceptable.
Quote:
Second your code needs to dereference the pointer, hence it should be p->constructor(5);
I know. This was supposed to be some kind of pseudo code to make my intentions clear.
Consider the following situation: you have a class which uses only a very small amount of memory, say 1 byte, and you can't change that class (its declaration and definition are given).
Now, using new will occupy at least 12 bytes on my 32-bit machine (new[] is not an option, for certain reasons). If you create 2^20 instances, 11 MiB will be wasted for just 1 MiB payload. This is hardly acceptable.
I should add: in my case, malloc() will not add the mentioned overhead, because I can malloc() a large chunk of memory (say, 16 kiB), and fill it with instances of A. These instances won't be free()'d before program termination, so they do not have to be free()'d individually.
I know that the described situation is rare (and I just had an idea how I can use new[] after all).
Still, I would like to know if it is possible, and how (out of curiousity ).
Consider the following situation: you have a class which uses only a very small amount of memory, say 1 byte, and you can't change that class (its declaration and definition are given).
Now, using new will occupy at least 12 bytes on my 32-bit machine
I'm sorry but I don't follow you line of argument here. Using new will return a pointer to your object, which would be 4 bytes, but if you only want to store the object then that will be back to the 1 byte. I'm sure I've missed something but I can't see where the 12 bytes come from.
new uses either the same or a similar implementation as malloc(). The glibc implementation uses (on 32-bit systems) 4 bytes before and 4 bytes after the payload memory area. These two values are aligned to 4-byte borders, hence 12 bytes are needed (plus the internal management overhead of malloc(), which I didn't count).
The returned pointer has nothing to do with this calculation (as it is needed either way).
Are there compelling reasons for the individual bytes to be held as individual objects? I would look at having the object to hold more data, or maybe even removing the object concept and running this part procedurally, because holding it as an object will have other overheads such as those that will allow rtti to work.
These are the a few ways a program is going to get memory to store anything:
1. Have a global or static variable, in which case the memory is set aside at the beginning of the program
2. Have a local variable, which is stored on the stack
3. Have an instance variable, in which case it would be stored as part of however the instance is stored
4. Allocate it with "new" from the heap
So if you don't like any of the above methods, then tough luck.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.