Abusing dynamic memory

Don't people understand that all the really need are references to instantiate and create objects if they aren't using polymorphism? I see it a lot in c++ code here, abuse of the dynamic allocation functionality for trivial short term usage.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class SomeClass
{
private:

unsigned int g_some_data;

void store( unsigned int j )
{
  g_some_data = j;
} 
 public:
  SomeClass(){}
  ~SomeClass(){}

  unsigned int do_something( unsigned int i )
 {
   unsigned int j = 1;
   while( j < (i*(i+1)/2) )
   {
     j*= i;
   }
   this->store(j);

   return get_something();
 }

 void get_something()
{
  return g_some_data;
}

};

int main()
{
  SomeClass* pSomething = new SomeClass();//this practice

  //do something really trivial
  int ret = pSomething->do_something( 1000 );

  delete pSomething;

  pSomething = 0;//if they are a good programmer

  return ret;
}
Last edited on
Well yes, that's abuse of new. Beginners coming from Java sometimes do this because they're used to it.
Line 39 is wrong, by the way.
Don't people understand that all the really need are references to instantiate and create objects if they aren't using polymorphism?


If you want to instantiate objects, you definitely need something more than references.


pSomething = 0;//if they are a good programmer

I'm curious. Why do you consider that a good practice?
cire wrote:
I'm curious. Why do you consider that a good practice?

Why don't you? I find that a good practice. Remember that pSomething, at that point in the code, points to deleted memory.
EssGeEich wrote:
Why don't you?


First, I generally avoid this situation by using a smart pointer.

Second, if I've deallocated the memory, I'm not going to be accessing the variable again. And if I do accidentally access it again, I want my program to crash so that I know something needs to be fixed. If this is a logic problem that involves deleting the same memory more than once and the pointer is set to null, the issue is effectively hidden but not solved.

Finally, it just feels really cheesy to me, especially in a situation like that in the code above where the variable immediately goes out of scope after the deletion.
cire wrote:
Finally, it just feels really cheesy to me, especially in a situation like that in the code above where the variable immediately goes out of scope after the deletion.

Aha, so the question was situation-based, all right, my bad I tought you meant not to do it almost at all.
No, the question wasn't situational. I don't really care if people do it; it's not particularly heinous, but I wouldn't consider it good practice. It strikes me as a solution looking for a problem.
cire wrote:
No, the question wasn't situational.

I bet it is, if you was going to build your own smart pointer, you'd leave the pointer pointing to some random memory you don't "own" ? In that SITUATION you'd set the pointer to 0.
Aha, so the question was situation-based, all right, my bad I tought you meant not to do it almost at all.

Some corner cases aside, it usually boils down to two situations: you own the object pointed to and therefore use a smart pointer or you don't and consequently have no business deleting the object anyway.

And if I do accidentally access it again, I want my program to crash so that I know something needs to be fixed.

Well, that's a reason that speaks for setting it to null - as opposed to a double free problem, dereferencing a null pointer crashes the program reliably, while the chance that dereferencing a pointer that you just deleted is usually very low or even zero (depending on the implementation and the object size).

In that SITUATION you'd set the pointer to 0.

Yes, but that's the direct result of the user calling reset(nullptr).

It's also a difference whether you set a pointer to null because it's required for the program to work correctly or if you're doing it as a matter of style on the off chance that you accidentally dereference or delete the pointer again.
Last edited on
Well, that's a reason that speaks for setting it to null - as opposed to a double free problem, dereferencing a null pointer crashes the program reliably, while the chance that dereferencing a pointer that you just deleted is usually very low or even zero (depending on the implementation and the object size).


That's true. On the other hand, the double deletion problem has no chance of causing a crash that way (decreasing it's chance of discovery.) You can reasonably justify going either way with it, which means, at least to me, that it's not "good practice." It is simply "a practice," which is at odds with the OP's assertion.



If you want to instantiate objects, you definitely need something more than references.


The object declaration is a reference, it is a segment of memory that you don't directly address but indirectly so by name. it is instantiated automatically by the compiler, meaning that the compiler determines how much space it needs for that object to work in the code.


I'm curious. Why do you consider that a good practice?


Because they actually THOUGHT about pointing the pointer to NULL so that if they want to use the same pointer again maybe by accident it would be more obvious than a garbage address. Better to debug a pointer that you know that you cleared to null leaving only the case that you tried to use it rather than any other case.
Last edited on
In C++, avoid the problem; use smart pointers.

In C, (or in C++ if raw owning-pointers to dynamically allocated memory have to be used), most of the coding guidelines that I have seen recommend setting pointers to null (or another valid value) immediately after the pointed memory has been freed.
For instance, CERT: http://www.securecoding.cert.org/confluence/display/cplusplus/MEM01-CPP.+Store+a+valid+value+in+pointers+immediately+after+deallocation
As a hobbyist, I rarely think of these things from a security standpoint. Thanks for sharing that perspective, JLB.


DeXecipher wrote:
The object declaration is a reference...

If you're using your own made-up definitions, I guess you can make whatever claims you'd like. Adieu.
DeXecipher wrote:
The object declaration is a reference...
cire wrote:
If you're using your own made-up definitions, I guess you can make whatever claims you'd like. Adieu.


Well I hope I'm precise enough, but the object in question is a block of memory on the stack. You can get a pointer to it because a pointer can point to stack memory. Reference use internally pointer from what i heard (not sure tho, maybe some clarifications?) so I guess it's not right, as an object isn't itself a pointer.

800th Post!
Last edited on
True, the object data, itself is not a pointer, when you use its declaration to call a member function for instance its not direct because you don't implicitly say call 0x1D1AFB2C.

edit: replace "implicitly" with "explicitly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

struct SomeObject
{
  char some_data;
};

int main()
{

SomeObject some_identifier;//structs are almost equivalent to classes
                                              //the difference is that classes are private,
                                             //by default for instance data and methods
    
some_identifier.some_data = 32; //indirectly addressing data by name
                                                     //since references are essentially pointers
                                                     //then you are using a pointer, implicitly
                                                     //to change the value of this data,
                                                     //and the pointer is the base address
                                                     //of the object some_identifier
                 
return 0;
}
Last edited on
//indirectly addressing data by name
//since references are essentially pointers
//then you are using a pointer, implicitly
//to change the value of this data,
//and the pointer is the base address
//of the object some_identifier
This is not necessarily true. For example, the compiler could decide it doesn't need to allocate some_identifier on the stack and just allocate a register for some_identifier.some_data. Then there would be no addresses at all.
More abstractly, a hypothetical implementation could exist that doesn't access stack objects by address, but by name. A run time symbol table of sorts.
EssGeEich wrote:
Well I hope I'm precise enough, but the object in question is a block of memory on the stack.

It may or may not be. C++ has no notion of a stack in this context. All we know is that the object (see code below) in question is of automatic storage duration and has no linkage.


You can get a pointer to it because a pointer can point to stack memory.

You can get a pointer to it because the standard says you can.

1
2
3
4
5
6
int main()
{
    int object = 0 ;
    int * objectAddress = &object ;
    return ++object ;
}

Do you think an optimizing compiler is going to allocate object on the stack?


Reference use internally pointer from what i heard (not sure tho, maybe some clarifications?) so I guess it's not right, as an object isn't itself a pointer.

A reference may be implemented internally as a pointer. In some cases, there may be no internal representation for a reference at all. I don't see how what the compiler might do behind the scenes is really relevant, especially as there were (apparently) no actual C++ reference types included previously in the discussion, just an ad hoc definition that is clearly not in sync with normal use of the term in the context of the C++ type system.
> when you use its declaration to call a member function for instance its not direct
> because you don't implicitly say call 0x1D1AFB2C.
Yes, we can.

Suppose that the variable does allocate in the stack.
Suppose that you want to access it, then the compiler (at build time) decide to replace all calls to your variable to the memory address that it will be.

Indirect address means that you will read the address at run-time (from the pointer) and then go there to operate
i meant explicitly :D instead of implicitly. excuse my typo
Still, you are not using a pointer.
Topic archived. No new replies allowed.