A pointer points to a memory location containing a specified value right? If a pointer is defined without something to point at, it can point anywhere, right? Here is my question: What are the practical uses of pointers? I mean why wouldn't you just make a reference to the variable itself instead of having one more name to remember?
fireballnelson 0 Newbie Poster
Comatose 290 Taboo Programmer Team Colleague
int *x = new int();
How can you dynamically allocate memory on the heap using a reference?
dougy83 74 Posting Whiz in Training
How can you dynamically allocate memory on the heap using a reference?
int &x = *new int();
This should do it.
Comatose commented: Nice Job +8
Comatose 290 Taboo Programmer Team Colleague
Well shut me up.....
Murtan 317 Practically a Master Poster
dougy83 you could make that assignment to hold the allocation, but to me it looks like a memory leak waiting to happen and in a professional setting I would fail your code review for it.
There are also data structures that lend themselves to pointers, for example linked lists.
As another example I can remember a buffer that we implemented between a producer and a consumer. The producer tended to produce data in bursts and we couldn't make the producer wait until the consumer cleared out enough of the buffer. We ended up growing the buffer when it ran out of space. (The allocation of a new buffer and copying the data with memcpy was pretty quick.) The class that managed the buffer had to use a pointer to reference the buffer and could not have used a reference.
ArkM 1,090 Postaholic
dougy83 you could make that assignment to hold the allocation, but to me it looks like a memory leak waiting to happen and in a professional setting I would fail your code review for it.
It depends on context. For example, it's all right in a proxy class implementation:
// Declarations (no dependencies)
class A;
class ProxyA {
public:
ProxyA();
virtual ~ProxyA();
virtual void doit();
// ... other interface members
private:
A& a;
};
// Implementation with a very specific
// types and other dependencies...
class A {
public:
void done() {
std::cout << "Done!" << std::endl;
}
};
ProxyA::ProxyA():a(*new A)
{}
ProxyA::~ProxyA() {
delete &a;
}
void ProxyA::doit() { return a.done(); }
// You have comfort and clear reference to
// the real handler class in Proxy members.
// No need in pointer != 0 tests in member functions...
It seems sacramental Type* p = new Type;
"looks like a memory leak waiting to happen" for language purists (and C#/Java guys ;) )...
Murtan 317 Practically a Master Poster
I will agree that the allocation will not leak if the ProxyA doesn't get lost, but in that context, why allocate it at all?
It could just be a member of the proxy.
class ProxyA {
public:
ProxyA();
virtual ~ProxyA();
virtual void doit();
// ... other interface members
private:
A a;
};
Then you never have to allocate or deallocate it explicitly.
ArkM 1,090 Postaholic
You don't understand: it's the case when class A depends on a very specific headers, may be #import and other implementation-specific stuff. If you declare A a;
then you MUST include all these stuff in all your modules (for example, class A has _bstr_t and _variant_t and _ConnectionPtr and other exotic type members) - it's too cumbersome (sometimes dangerous) practice.
The ProxyA is one of possible forms of such peculiarities incapsulation.
Murtan 317 Practically a Master Poster
Ok so its a form of hiding the full implementation of A from the users of ProxyA which provides a subset of the full implementation without having to re-write any code because it uses A to do the work.
Because ProxyA only has a reference (or pointer) to an A, you don't have to have the full A headers in the ProxyA header file (which the users of ProxyA will have to include) you only have to have them in the ProxyA source file. I can see that as a useful abstraction, and in the context you presented it the reference holding the allocation would be safe.
You mentioned that the members of ProxyA don't have to keep checking if the pointer is NULL because you use a reference. The only protection you have is that the constructor will fail if you can't get memory allocated. If you added your own test to the constructor, you could get the same safety with a pointer, but you do have to do the extra work.
The problem I've always encountered with this type of proxy was that it either the features proxied were limited, or the proxy would have to re-declare items from the class being proxied. An example might be an enum value used for a paramter to one of the methods of the A class. Either ProxyA must presume (or be able to determine for itself) what the enum parameter should be, or the enum has to be re-declared in the ProxyA scope. (and I hate duplicating anything, especially by hand.) If you throw in a structure passed by reference to another method, and you start to wonder just how much of the A header you didn't have to include.
Liinker 3 Newbie Poster
A pointer points to a memory location containing a specified value right? If a pointer is defined without something to point at, it can point anywhere, right? Here is my question: What are the practical uses of pointers? I mean why wouldn't you just make a reference to the variable itself instead of having one more name to remember?
A pointer is basically just an integer. That integer represents a memory location. When you declare an integer without giving it a value, it COULD contain any number, but that variable will be useless to you unless you assign a specific value to it. The same holds true for pointers, however, its much more dangerous to use pointers like that because without knowing exactly what that pointer 'points' to, you could be messing with a memory address that shouldn't be messed with. Ultimately causing errors and crashes.
I mostly use pointers while communicating with USB devices. Most times, I've had to poll the device to return me some data. Rather than having the device create a structure, fill it, and return the needed data, I call a function inside the devices *.dll and pass it a pointer to a structure already defined in my code. The device then simply uses that pointer to my structure and fills it with the data I need. It can then return a simple integer, which can be used for error checking.
Don't know if that helps at all. Just my $0.02.
Murtan commented: I like it, short sweet and pretty clear +2
ArkM 1,090 Postaholic
Fortunately, it's not a problem for this kind of a proxy because class ProxyA does not provide full interface of class A. Moreover, the class A is rather an implementation object container than an interface to desired functionality. As usually, all enums (and other working interface members) are declared in ProxyA (or other public class) but not in such "driver-type" classes.
Back to the topic: I think Type& ref = *new Type
construct is entirely legal one. In other words, this construct meets the C++ language requirements (and spirit of the language). The only "defect": it's not habitual C-like construct, but C != C++...
Murtan 317 Practically a Master Poster
I agreed earlier that the construct was legal. But then code obfuscation contests produce legal code, but I wouldn't accept them as a deliverables either.
My point is that although the syntax is perfectly legal and permissable, it is less maintainable. I would be less likely to notice that you neglected to release the memory (if I didn't complain about how you stored the allocation in the first place).
There is no real cost to using the Type * ptr = new Type
other than having to type ->
rather than .
. But I would argue for longer more verbose variable names as well, so I'm not totally against a little typing.
Some of this may be biased from my background. I've been working for over 15 years in control software systems where the software runs 24x7, preferably for months at a time and we can't really afford to waste any of the system resources.
Given enough time, even a little leak can cause problems. So we spend a little extra time when there are pointers involved to make sure that if they were allocated the ownership (and deallocation responsibilities) are well defined and followed.
If you made a habit of taking arbitrary pointers and assigning them to references, you would have to spend the extra time looking at references as well.
So in a well defined case (like your ProxyA example) where I can clearly see the allocation and the deallocation, I don't have a huge issue with the construct. I would probably still have used an A * a
in the proxy, but that is probably habit, I can accept that you prefer to see it as a reference.
But for example while it would be permissable to call the function foo( A & a)
with foo(*new A())
if you knew that foo would free the object (or didn't care if it leaked) I would argue that the whole concept would be bad form.
ArkM 1,090 Postaholic
Murtan, I understand your point of view (moreover, I share your views on this issue ;) - now we have some embedded software projects in progress).
The point is that references are not more dangerous beasts that pointers - and they are not more safety ones. Most of memory leak terrifying stories were born in C world (truth to tell I never had any troubles with pointers for over 30 years in PL/I, C and C++ ;) ). The C++ constructor/destructor discipline is a wonderful medicine to treat the leak disease. On the other hand we must count new/delete pairs but no need to try to delete any pointer or to keep alive any reference to avoid memory leaks.
References in C++ are comprehensible and usual types for me, so I don't consider &=*
triad harmful. It's the other story that if the project coding discipline requires only C-like Type* declarations and -> qualifications then we must do it (or leave the project ;) ). Well, I have seen coding rules where any member access must been qualified by this->
. I'm not sure that such codes have extra quality thanks to this rule...
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.