Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
For some reason, I have decided to never use dynamic memory allocation in my program. This means all the variables in my program are static and the "new" constructor is never used. But the following code crashes, and produces a stack overflow exception:
VeryLargeObject x; // Global variable -> static memory
void ResetTheObject()
{
x = VeryLargeObject();
}
Obviously, all I want to do is give x the default value of VeryLargeObject, which is a structure containing a lot of different variables, with their own constructors of varying complexity (so there's quite some initialization work to do). But here the language/compiler has decided that this should happen on the stack before being copied, and since VeryLargeObject is too large for the stack, my program crashes.
However I have found the solution to this problem:
VeryLargeObject x;
void ResetTheObject()
{
new (&x) VeryLargeObject();
}
I had never heard of this before, yet it does exactly what I want. This is a "placement new". It calls the constructor on the already allocated (or simply static) memory provided by a pointer.
My question, since I have the solution, is a rant: Why isn't this the default behavior of the first code ? If there isn't a less hacky way of doing this (i.e without the word "new" having anything to do with it), then why? Also why does it send me back the pointer, even though I just provided it? I thought C++ was a great language, but this seems kind of ugly and not very well-thought-out.
First of all, turning on optimization might get you what you want with the first syntax. Without it, here's what you asked the compiler to do:
Create a temporary object of type VeryLargeObject.
Assign that into a global variable called x.
Since temporary objects need storage, the compiler allocates them on the stack. What the compiler is doing is, literally, what you asked the compiler to do.
The compiler may, if optimizations are turned on, understand that what the sequence is and save the copy. This requires that the compiler can positively prove to itself that the old value of x will not get in the way in any way. Since you admit that the initialization is quite complex, you can forgive the compiler if it did not manage to do so.
You have two options. You can either create an in-place initialization function and call that instead of the constructor, or you can use placement new, like you did.
The danger with placement new, as you used it, is that it replaces the old value of x without properly destructing it. It simply assumes that x is uninitialized. If that's okay for your use, then go ahead and use it. The compiler, for its part, is not allowed to assume that.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am still a beginner in c++, but I know something. I am studying the 1st term and I wanna make my own project, IMO it's the best way to learn to program. Anyway I wanna load data from file to dynamic array (and I know how to do that) but I to that job be done by special function and to that array be visible for other function (alternativity global). I know that using global variables is not good idea so I am thinking if it's possible to make variable friend with NO classes (bc I didn't use and learn classes yet)
Thanks in advance!
friend is not what you're looking for. A variable is just a named object. What you want to do here is not to somehow access the function's variable from the outside (that's not actually possible, function variables only exist when the function is executing). You want to transfer the object from one function to th other. That's done through the function's return value:
std::vector<int> readDataFromFile() {
std::vector<int> data;
// Read the file and store it into `data`
return data;
}
int main() {
std::vector<int> myData = readDataFromFile();
// Use `myData` as needed
}
You can see above that readDataFromFile works on its data variable, then returns it. This means that, right as readDataFromFile ends, myData in main (another, independent object) is initialized from data, and the data itself lives on.
Notes:
Do not use C-style arrays, new or delete. These are meant for compatibility with C and low-level memory management, not general use. A C++ dynamic array is an std::vector<YourType>.
Further notions:
Here myData is move-initialized, which means that no copy of the data is made: the dynamic array is transferred directly from data to myData
This is a case where NRVO can occur. That's an optimization which notices that data is redundant, and will replace it with direct access to myData, so there will only ever be one vector object throughout the program's execution. This is not observable in the general case., wo you don't need to worry about it.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
From book "The first hidden argument to the constructor is the this pointer"
Now when we write like
classname object;
Is it like first memory for the object is created and address of the object is pass to default constructor so that it can initializes the values of the class.
If this is the concept for object how memory is created, is it created by the OS ?
It depends on where you write your definition:
If you define your object at global scope the linker will figure out where to place the object in the program’s data area and make sure there is enough space. The same is true for all static objects, independent of whether they are static class members or function local statics.
If you define your object as a local object in a function it will be placed on the stack. The calling conventions on the system in use will arrange for enough space on the stack (assuming there is enough space on the stack to start with; otherwise you’d get a stack overflow).
If your definition is actually a member declaration, space for the object will be made in the containing object and the new object will be placed there.
Just for completeness, when using a new expression the space is allocated on the heap and the object is places there.
Another case are thread local objects which are placed somewhere on the thread’s stack.
Note that the placement of objects applies to all constructors: the only significance of the default constructor is that you don’t pass any arguments when constructing the object.
As John mentioned in the comments, there is no explicit information in the Standard on how the memory is allocated/managed. However, assuming that no compiler optimizations take place and that you are creating an object on the stack... then this will likely happen.
Given:
void f()
{
foo x;
}
The compiler will produce something like:
void f()
{
char foo_buffer[sizeof(foo)];
new (&foo_buffer) foo()
reinterpret_cast<foo*>(foo_buffer)->~foo();
}
The space for a foo instance is reserved on the stack, then the constructor is called on that space. At the end of the scope, the destructor is called.
When an object is created, the os will Create the space.when the object is created the os automatically calls the default constructor .
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Is it useful to create a pointer or an array of pointers on the heap ? if so when and why would I need to do so ?
For example:
#include <iostream>
class Box { /* things... */ };
int main(void){
// Single pointer on the heap
Box** pBox = new Box*(nullptr);
*pBox = new Box();
// Array of pointers on the heap
Box** pBoxes = new Box*[3]{};
pBoxes[0] = new Box();
pBoxes[1] = new Box();
pBoxes[2] = new Box();
// Delete pointers...
return 0;
}
EDIT: Just to make my question more clear ... I know dealing with raw pointers is not the best practice ... I just want to fully understand pointers and their uses as they are important part of c++ hence my question is (is it useful...).
The reasoning behind allocating any memory space on the heap or on the stack is not related to the type of variables allocated, it's related to how it's allocated and how it's meant to be used.
In any case, nowadays you should usually avoid new statements and use "managed" pointers, particularly the std::xxx variants.
From what i read, the heap has slower access speed than the stack so, I don't think that it is very useful to do what you are talking about.
Maybe this will help you trought your research: http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html
As another answer mentioned, usually actual access to the heap is slower than access to the stack, however access speed generally isn't the reason for creating and dealing with pointers.
The typical use case for pointers is to avoid copying data. When you're dealing with large objects and passing them between many functions, it is considered "better" to pass by reference rather than by value.
If you use the object from the stack (unless you pass it as a reference, but there are limitations when doing this) it makes a copy of the whole thing for the called method. When passing a pointer to a method, it is only copying an address.
See if this article helps you understand the differences.
Yes, there can be reasons to have pointers on the heap. A factory function that keeps track of every object it creates might store them in a vector, for example:
vector<unique_ptr<Box>> BoxFactory::allBoxes;
Box* BoxFactory::makeBox()
{
allBoxes.emplace_back(make_unique<Box>());
return allBoxes.back().get();
}
Note: some people have suggested that this is not double-indirection. It is:
// Accesses some_box_member of the first Box.
allBoxes.data()->get()->some_box_member
Just as with the OP's example, you have two pointers in play, not just one. The vector contains pointers which have been allocated on the heap, and those pointers contain another pointer that points to the Box object.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
When a function is called, lets say in c++, is it located in a specific place in memory since function pointers exist? If so where exactly? How about classes? Is there memory stored aside for class definitions?
Yes, functions are located in a specific place in memory. In the context of Virtual Memory (opposed to physical caches), they are stored below the Heap and below a section called the Data (global variables) in a section called Text. All of this is loaded up when the executable is read; this is all done in binary, which is one-to-one with assembly, so you'll never see this in your C code. However, if you know the processor well, you can sometimes still manipulate it into reading from the code section in your code. It may cause a segfault however, and generally you cannot write to the code section.
Just like pointers to variables, function pointers point to a place on the overall stack (see this helpful site). There is actually a register devoted to pointing to exactly which instruction the program is currently executing.
Class definitions and member functions also have a specific place on the stack; I'm not entirely sure, but I believe they go in Data.
All of this may be wrong, it is not my specialty. But as far as I know...
A function at runtime is a position in the executable that a "lower" part can call, altering the stack... never mind, I'll not try to explain this any further.
A class is not stored in memory. It is completely conceptual. Say you have the following structure.
struct idk
{
char* name;
int index;
void* data;
};
Well, new idk at runtime doesn't actually look at some kind of definition to know what to allocate. Instead the compiler figures everything out so that the end result is that new idk turns out to be the conceptual equivalent of new char [sizeof(idk)], though that is not taking into account alignment and packing. Anyway, so references also don't have any form of table to look at for what variables are where, they rather are also determined at compile-time, so that int n = idk_thing.index would perhaps act like int n = *((int*)(&idk_thing + sizeof(char*)); and so on.
And of course, a class's storage is implemented almost identically to that of a structure, and any class-specific functions are just plain old functions that, again, the compiler sets up a certain way so that it modifies variables in the class by accessing the storage of an instance of the class. I assume that this is done by passing a pointer to the storage to the function, which accesses that block of memory with offsets depending on what variable it is working with (just the same as what I was saying about structures).
Now, as for function pointers, assuming I am at least on the right track with the compiled equivalent of functions, I'd say that function pointers are just numbers to represent the location in the loaded executable that is the starting place for a function, just as a char* is a number meant to represent the location of a char in memory.
As for classes, in C++ (and all OOP languages, if that matters) they are typically created on the heap. Though C++ can create it on the stack if you ommit the new keyword, but that's generally not recommended because classes tend to be resource-heavy, but it means that you'll have a memory leak if you don't explicitly delete it.
For function pointers, they're usually just pointers in the stack pointing to seperate code blocks in read only memory.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Is the following ok?
int n=5;
map<string,int> * maps = (map<string,int> *)malloc(n*sizeof(map<string,int>));
for (int i=0; i<n; i++) {
maps[i] = map<string,int>();
char * i_str = (char *)malloc(10);
sprintf(i_str,"%d",i);
char * key = (char *)malloc(100);
strcpy(key,"key");
strcat(key,i_str);
(maps[i])[string(key)] = i*i;
}
I know people say to use new rather than malloc in C++. But if I do it this way, what if any problems can occur?
Edit: Code compiles fine and runs fine (g++ 4.6.3). Not sure why the question is on hold, but I just want to know if it's technically correct (I don't care about style). One thing I'm not sure is whether the line
maps[i] = map<string,int>();
is syntactically correct, and whether it really does lead to unexpected behaviour as one person suggested.
Someone has yet to provide a reference to the C++ specification that shows that what I'm doing is undefined. So this question is still not answered.
The main problem will be that the constructor of the map will not run.
Without the constructor, the map will be in an invalid state and will not work properly.
You can use placement new to manually call the constructor.
EDIT:
Just realized that you do try to make the map valid with:
maps[i] = map<string,int>();
However, this will not work because the map needs to be in a valid state before it can be copied into (and it is currently not valid at that point because it has not been constructed yet).
There are also many memory leaks in your program as well.
Make sure to either use smart pointers(note that you need to use new for smart pointers to work) or free every allocation.
The instruction:
map<string,int> * maps = (map<string,int> *)malloc(n*sizeof(map<string,int>));
reserves memory for storing maps, but does not initialize the memory (call the constructor) . Most likely the map's constructor here will require extra dynamic allocation.
Then
maps[i] = map<string,int>();
calls the map's copy assignment operator=, which supposed to clear the previous contents of the map, and replace it with new (blank) contents. However, since the former map is not in a valid state, you'll very likely go into trouble here. This is undefined behavior, and may do nothing, or it may crash, or do other random things, randomly.
You are also losing a lot of memory, since you never free the memory that you malloc.