473,800 Members | 2,578 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

what's the difference between delete ptr and ptr=0 -dont they accomplish the same

Sid
Hi,
I was going through this reference code and playing around with it.
The code (shown below) shows a class that represents a stack of string
pointers

In the code below in particular in the pop function, the code works
when I set stack[index]=0 but when I say delete stack[index] the code
compiles but does not execute -I am only trying to "delete
stack[index]" after I have copied the relevant data pointed by it
into variable "rv", so why is this program not allowing me to free
stack[index] (which is nothing but a pointer to a string) ?.

Also, when I comment the stack[index] and the delete stack[index], the
code executes to completion but doesn't this actually create a memory
leak since stack[index] is never deallocated or freed and if so how is
the program executing to completion without any errors ?

I would greatly appreciate any feedback.

#include <string>
#include <iostream>
using namespace std;

class StringStack {
static const int size = 100;
const string* stack[size];
int index;
public:
StringStack();
void push(const string* s);
const string* pop();
};

StringStack::St ringStack() : index(0) {
memset(stack, 0, size * sizeof(string*) );
}

void StringStack::pu sh(const string* s) {
if(index < size)
stack[index++] = s;
}

const string* StringStack::po p() {
if(index > 0) {
const string* rv = stack[--index];
stack[index] = 0; // this works
//delete stack[index]; // doesn't work
return rv;
}
return 0;
}

string iceCream[] = {
"pralines & cream",
"fudge ripple",
"jamocha almond fudge",
"wild mountain blackberry",
"raspberry sorbet",
"lemon swirl",
"rocky road",
"deep chocolate fudge"
};
const int iCsz =
sizeof iceCream / sizeof *iceCream;

int main() {
cout << "size of iceCream="<< sizeof iceCream << endl;
cout << "size of *iceCream="<< sizeof *iceCream << endl;

StringStack ss;
for(int i = 0; i < iCsz; i++)
ss.push(&iceCre am[i]);
const string* cp;
while((cp = ss.pop()) != 0)
cout << *cp << endl;
} ///:~
Jul 22 '05 #1
5 1739
On 28 Jul 2004 00:31:46 -0700, Sid <si***********@ gmail.com> wrote:
Hi,
I was going through this reference code and playing around with it.
The code (shown below) shows a class that represents a stack of string
pointers

In the code below in particular in the pop function, the code works
when I set stack[index]=0 but when I say delete stack[index] the code
compiles but does not execute -I am only trying to "delete
stack[index]" after I have copied the relevant data pointed by it
into variable "rv", so why is this program not allowing me to free
stack[index] (which is nothing but a pointer to a string) ?.
Nowhere in your code do you use new, so you don't need to use delete.

Also, when I comment the stack[index] and the delete stack[index], the
code executes to completion but doesn't this actually create a memory
leak since stack[index] is never deallocated or freed and if so how is
the program executing to completion without any errors ?


There is no memory leak because you never allocated any memory. For every
time you call new you should also call delete, if you never call new, you
never need to call delete.

john
Jul 22 '05 #2
void StringStack::pu sh(const string* s) {
if(index < size)
stack[index++] = s;
}
You are aware that you only store pointers here, are you? If you do
this:

string s = new string("Hello") ;
StringStack st;
st.push(s);
delete s; // Now you've got a problem when trying to use st.pop();

string iceCream[] = {
"pralines & cream",
"deep chocolate fudge"
};


Now you make a static field:

int *a = {3,4,5};

you cannot delete [] a. You would have to use:
int *a = new int[3];

What do you want to do? Store an array of strings or pointers to
strings that _must_ exist all the time the array exists? Don't
reinvent the wheel.

#inlcude <stack>
#include <string>

std::stack<std: :string> AStringStack;
_or_
std::stack<std: :string*> APointerStack;

HTH,

--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%c gl%ssic%ccom%c" , "ma", 58, 'g', 64, "ba", 46, 10);}

_______________ _______________ __________
Looking for a good game? Do it yourself!
GLBasic - you can do
www.GLBasic.com



Jul 22 '05 #3
> I am only trying to "delete
stack[index]" after I have copied the relevant data pointed by it
into variable "rv", so why is this program not allowing me to free
stack[index] (which is nothing but a pointer to a string) ?
You don't copy the data "stack[--index]" points to - you only copy the
pointer itself.
class StringStack {
static const int size = 100;
const string* stack[size];
int index;
public:
StringStack();
Having no destructor here works for your "string iceCream[]" example,
but iff the string instances are allocated on the free store, usage of "StringStac k"
will likely lead to memory leaks basically because of the following:
If the user assumes that "push()" and "pop()" both change ownership over
the "string" instance (in the sense, that after "push()" ownership is held
by the instance of "StringStac k" instead of the caller and after "pop()" the
caller again own the "string" instance instead of the "StringStac k"), then noone
ever "delete"s the string instances on destruction of a non-empty "StringStac k".
void push(const string* s);
const string* pop();
}; void StringStack::pu sh(const string* s) {
if(index < size)
stack[index++] = s;
}
Just a comment: You should somehow signal "index>=siz e" to the caller -
either by throwing an exception or by means of a "bool" return value.

In my opinion the "push()" should clearly change ownership over the "string"
instance from the caller to the "StringStac k" instance as already indicated above.
const string* StringStack::po p() {
if(index > 0) {
const string* rv = stack[--index];
stack[index] = 0; // this works
//delete stack[index]; // doesn't work
return rv;
}
return 0;
}


"delete" can't work - as said "const string* rv = stack[--index];" only
copies the pointer, not the string. So "pop()" should clearly change ownership
over the "string" instance from the "StringStac k" instance to the caller
as already indicated above. Another thing is, that "stack[index] = 0;" doesn't
serve for any purpose here.

As others have posted, consider to go for "std::stack <>" instead of "StringStac k",
but note that if you go for "std::stack < std::string * >" the above comment on a
missing destructor also applies, because standard containers don't take ownership
because of their value semantics.

Cheers,
Philipp.
Jul 22 '05 #4


int* p_number;

p_number = 0;

p_number = reinterpret_cas t<int*>(5678);

p_number = reinterpret_cas t<int*>(8764);
That's exactly like:
int number;

number = 0;

number = 5678;

number = 8764;
"p_number" is a variable just like "number".

The type of "number" is "int"

The type of "p_number" is "int*".

They're both variables and they're value can be set and read.
As for "delete", it's like a function that takes in a memory address as an
argument. It frees any memory that has been allocated at this address. It
can only be used in conjunction with "new".

int* p_number = 0;

p_number = reinterpret_cas t<int*>(8888);

delete p_number;
Here, "delete" is being called with the value of "p_number" as a parameter.
The value of "p_number" is the memory address 8888.

As no memory was allocated by "new" at that address, what we have here is
bad code, it's "undefined behaviour". Here's a legitamate use of "delete":
int* p_number = new int;

//Now, p_number contains a value, a memory address, let's say it's 98733

*p_number = 56;

SomeFuncThatTak esInt(*p_number ); //Is given 56

SomeFuncThatTak esIntPointer(p_ number); //Is given 98733

delete p_number; //Is given 98733
Here, "delete" is called and given the value stored inside the variable
"p_number", which is 98733. It deallocates the memory at that address which
was allocated via "new". This is how "new" and "delete" are supposed to
work. So, in summation:
p_number = 0;

All it does is change the value of a variable. It doesn't allocate or
deallocate memory.

p_number = new int;

"new" is like a function that returns a memory address. "new" allocates
memory and then gives you the address of that memory.

delete p_number;

"delete" is like a function that takes a memory address as an argument
(except there's no parenthesis!). It deallocates memory according to the
memory address it's supplied with. If memory was previously located at that
address via "new", then all is fine and dandy; if the contrary, then it's
Undefined Behaviour.
Hope that helps.

And just remember that a pointer variable is just like any other variable.
Where an "int" stores an integer number, an "int*" stores a memory address.
Just as an example, on WinXP, an "int" takes up 32 bits in memory, and an
"int*" takes up 32 bits in memory. You could have something like a "double",
which takes up maybe 80 bits in memory, but a "double*" will only take up 32
bits, because 32 bits is all that's needed to store a memory address on
WinXP.
-JKop


Jul 22 '05 #5
Sid
THANKS A BUNCH FOLKS - I appreciate your time and effort.
JKop <NU**@NULL.NULL > wrote in message news:<GZ******* **********@news .indigo.ie>...
int* p_number;

p_number = 0;

p_number = reinterpret_cas t<int*>(5678);

p_number = reinterpret_cas t<int*>(8764);
That's exactly like:
int number;

number = 0;

number = 5678;

number = 8764;
"p_number" is a variable just like "number".

The type of "number" is "int"

The type of "p_number" is "int*".

They're both variables and they're value can be set and read.
As for "delete", it's like a function that takes in a memory address as an
argument. It frees any memory that has been allocated at this address. It
can only be used in conjunction with "new".

int* p_number = 0;

p_number = reinterpret_cas t<int*>(8888);

delete p_number;
Here, "delete" is being called with the value of "p_number" as a parameter.
The value of "p_number" is the memory address 8888.

As no memory was allocated by "new" at that address, what we have here is
bad code, it's "undefined behaviour". Here's a legitamate use of "delete":
int* p_number = new int;

//Now, p_number contains a value, a memory address, let's say it's 98733

*p_number = 56;

SomeFuncThatTak esInt(*p_number ); //Is given 56

SomeFuncThatTak esIntPointer(p_ number); //Is given 98733

delete p_number; //Is given 98733
Here, "delete" is called and given the value stored inside the variable
"p_number", which is 98733. It deallocates the memory at that address which
was allocated via "new". This is how "new" and "delete" are supposed to
work. So, in summation:
p_number = 0;

All it does is change the value of a variable. It doesn't allocate or
deallocate memory.

p_number = new int;

"new" is like a function that returns a memory address. "new" allocates
memory and then gives you the address of that memory.

delete p_number;

"delete" is like a function that takes a memory address as an argument
(except there's no parenthesis!). It deallocates memory according to the
memory address it's supplied with. If memory was previously located at that
address via "new", then all is fine and dandy; if the contrary, then it's
Undefined Behaviour.
Hope that helps.

And just remember that a pointer variable is just like any other variable.
Where an "int" stores an integer number, an "int*" stores a memory address.
Just as an example, on WinXP, an "int" takes up 32 bits in memory, and an
"int*" takes up 32 bits in memory. You could have something like a "double",
which takes up maybe 80 bits in memory, but a "double*" will only take up 32
bits, because 32 bits is all that's needed to store a memory address on
WinXP.
-JKop

Jul 22 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
6997
by: foo | last post by:
I'm creating a debug class called debug_mem_allocation for the purpose of finding memory leaks. I used macro's to replace the new and delete operators. My problem is with trying to replace the delete operator with a macro. I can't replace the delete operator by using void* as the first parameter, because then my code will not be able to modify the calling function's pointer, nor would it get the source file name and line number.
14
4610
by: A | last post by:
Hi, Consider this: char* ptr = "a string"; Is ptr a pointer to a dynamically created object for which i must use the delete operator to deallocate memory? I'm sure the "a string" part creates an array of characters, and returns a pointer to the first element.
7
7138
by: A | last post by:
Hi, consider this: char* aClass::printHello() { char* ptr = new char; ptr = "Hello"; return ptr;
3
2929
by: hs | last post by:
hi, If I have a C struct in C++ like the following: struct { int a; int b; int c; char d; char *ptr;
6
1999
by: R.Z. | last post by:
i'm using a class from some api that is said to automatically call its destructor when its out of scope and deallocate memory. i create instances of this class using "new" operator. do i have to explicitly call delete on these instances when i no longer need them?
7
16547
by: morz | last post by:
i just search for a while in c++ groups but cannot find good answer. i have code like this: int **ptr; ptr = new char *; ptr = new int(5); ptr = new int(16);
9
1454
by: pavan734 | last post by:
Hello, I have a array of double pointers as shown below dummy_class **ptr ; //assume dummy class to be some c++ class I have allocated it like this: for(int i = 0 ; i<10 ; i++) { ptr = new dummy_class* ; for(int j=0 ; j<5 ; j++) // This 5 is because of previous allocation of 5
7
2807
by: Michael | last post by:
Hi, What's the benefit to dynamically allocate memory? using namespace std; int main() { char* ptr; ptr="abc";
7
2291
by: Yi | last post by:
Two questions about the following code sample: --- code begins --- //class IPv4 is defined elsewhere list<IPv4ip_list; for (int i=1; i<=9; i++) { char addr; sprintf(addr, "%d.%d.%d.%d", i,i,i,i);
2
3858
by: Amal P | last post by:
Hi, This is the program that i made to test the usage of inline function. I am using vc 6.0 compiler. Please see the below program. int NonInline( int a, int b ) { return ( a b )? a: b; }
0
9551
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10507
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10279
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
7582
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5473
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5607
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4150
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3765
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2948
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.