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.
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 does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
I have two classes. One that creates a resource, which is then sent to the other class which stores it for access by different parts of the program. What I do is:
typedef std::shared_ptr<Object> ObjectPtr;
ObjectPtr CreatorClass::Create()
{
ObjectPtr(new Object);
// ...
return ObjectPtr;
}
void StorageClass::Store(ObjectPtr obj)
{
myVector.push_back(obj);
}
ObjectPtr StorageClass::Get(int index)
{
return myVector[index];
}
My questions are:
Am I correct in using shared_ptr or should I use something else?
Should I be passing ObjectPtr by value to Store function and from Get function?
Am I correct in using shared_ptr or should I use something else?
You are correct if you need shared ownership. Otherwise you are wrong.
Should I be passing ObjectPtr by value to Store function
Yes. Although you could still do .push_back(std::move(obj)) to avoid a needless copy.
and from Get function?
Depends on whether you want to
modify the original shared_ptr in the vector, then return by non-const reference,
just observe it, then return by const reference
none of the above, i.e. get you own copy of it, then return by value.
Well, generally speaking, you are not doing it very efficiently. I see multiple issues with the code, almost close to antipattern.
Omnipresent Creators. My gosh, I hate them. What's the point of a
'creator' in your example? Why can't the object be created by the
user directly?
Store function. It has two issues. First it does nothing apart putting an element to the vector, coupled with sister get, which
simply extracts. Given that, those two functions should be sent to
meet their Creator (pun intended). Instead, myVector should be
exposed to class users. Otherwise, you are severely limiting user
experience (for instance, how would they even know if they can call
get with given index? They don't know the size of the vector!). Avoid
getters and setters.
Second issue with Store - if we imagine that Store does more than simply pushing stuff to vector, and thus it's existence is justified,
it accepts shared pointer by value. Which means, you are atomically
incrementing the counter. Performance weeps. Pass shared pointer by
reference to reduce the impact. Better yet, do not use shared
ponters. There usage is not justified in 99% cases I've seen.
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 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 9 years ago.
Improve this question
In some code I have been working on, I am passing pointers into classes that aren't necessarily managed specifically by the class to which they are passed. If the class is destroyed then I check to see if the pointer's memory has or has not already been deallocated. The problem I have is that, if a pointer is deallocated and set to NULL before the class's destructor is called then I end up with a dangling pointer. The class ends up seeing the pointer is still non-NULL and tries to delete it which causes a segmentation fault. The best solution I could think of for this is to store the pointer by reference as shown below:
class PtrReferenceClass {
public:
PtrReferenceClass(int*& i_) : i(i_) {}
void run() {
if(i == NULL)
cout << "pointer is null\n";
else
cout << "pointer isn't null\n";
}
int*& i;
};
int main() {
int* i = new int(5);
PtrReferenceClass test(i);
test.run();
delete i;
i = NULL;
test.run();
return 0;
}
As expected, the output is:
pointer isn't null
pointer is null
Ofcourse when the pointer isn't store by reference I end up with a dangling pointer.
My question is as to whether or not this is generally considered to be a good programming practice. Are there any drawbacks to this solution or is there a better convention?
It depends upon what you are trying to accomplish.
If you want the memory around for your class use C++11's std::shared_ptr everywhere instead of an int*.
If you don't need the memory around for your class use C++11's std::weak_ptr.
As far as holding onto pointers in a class, that's not bad if they're wrapped in one of C++'s pointer wrappers. You can just hang onto raw pointers, but in general you should only do that if speed is an extreme concern.
You could check for NULLness in the destructor of PtrReferenceClass. A much better alternative whould be to use a shared_ptr or really clarify ownership of i.
Agree with #Paranaix in main thread comment, as well as #ToniBig, I can't really think of a situation where you would need this. Such a thing is probably to protect against horrible programmer error. You should also keep in mind that you are storing a reference to the pointer i, and that reference will be left dangling when the pointer i goes out of scope, regardless of whether the memory i refers to has been deallocated or not. SO in conclusion, please don't do this.
All you've done is trade one lifetime problem for another. The new problem may be easier to solve... or it may not.
Now you can detect that the object is gone... as long as something has kept the pointer variable alive.
Think carefully about your variable lifetimes, and whether a reference-to-pointer (or equivalently, pointer to pointer) makes sense should become clear.
There certainly are cases where double indirection is valuable. I will leave you with a quote: "Any problem in computer science can be solved by adding another layer of indirection"
These are options :
give ownership to class and manage lifecycle inside it.plus with safe
setter method for changing it when you want. Again do it if you have to create or obtain that pointer outside,otherwise just do all inside.
only pass that pointer to methods that will use it and when
needed.void run(int* i).
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 9 years ago.
Improve this question
For deleting and an array of element we use delete[].
Is it possible to delete the pointers the way I am doing below?
ClassA* object = new ClassA();
ClassA* pointer1 = object;
ClassA* object2 = new ClassA();
ClassA* pointer2 = object2;
delete pointer1,pointer2;
Why its not possible to use delete this way?
[Edit]
Can I put it like, what are the drawbacks due to which the above delete has not been implemented?
It's not possible, because there is no provision for it in the C++ language definition. I'm not sure there is any "good" answer to why the language doesn't support a list of items for delete, except for the fact that it's simpler to not do that.
You need to write one delete for each variable. Of course, if you have many pointerX, then you probably should be using an array instead, and use a loop to delete the objects.
Edit: Of course, if you are calling delete in many places in your code, you are probably doing something wrong - or at least, you are not following the RAII principles very well. It's of course necessary to learn/understand dynamic allocation to have full understanding of the language, but you should really avoid calling both new and delete in your own code - let someone else sort that out (or write classes that do "the right thing")
It is not working this way. delete is a command for a single pointer. You can put the pointers in a structure (e.g. array) or a container (e.g. using a vector container class) and delete for each one of them by iterating the structure/container.