|
-
February 7th, 2003, 08:01 PM
#1
typedef and pointer deletion issues
Is there any particular issue between typedef and pointers?
the code below crashes:
Code:
#include <iostream>
using namespace std;
typedef unsigned short int uShort;
int main()
{
uShort a = 45;
uShort * ipa = new uShort;
ipa = &a;
*ipa = 100;
uShort newData = *ipa;
cout<<newData <<endl;
delete ipa;
ipa = 0;
}
while the code below works fine:
Code:
#include <iostream>
using namespace std;
int main()
{
int a = 45;
int * ipa = new int;
ipa = &a;
*ipa = 100;
int newData = *ipa;
cout<<newData <<endl;
delete ipa;
ipa = 0;
}
-
February 7th, 2003, 08:40 PM
#2
They should both crash. You are attempting to delete a stack variable through a pointer which, although originally pointing to a free store variable, is pointed to "a" and then a delete attempt.
*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
"It's hard to believe in something you don't understand." -- the sidhi X-files episode
galathaea: prankster, fablist, magician, liar
-
February 7th, 2003, 09:33 PM
#3
Originally posted by galathaea
They should both crash.
Well, the second code does not. Don't we have to use "delete" when we create pointers with "new" to clean up?
You are attempting to delete a stack variable through a pointer which, although originally pointing to a free store variable, is pointed to "a" and then a delete attempt.
Can you rephrase that?
I am trying to delete "ipa", which is a pointer I created with "new".
Is "ipa = &a;" the reason why I can't delete?
Why would one crash and not the other when they only differ in the macro?
-
February 7th, 2003, 10:52 PM
#4
Look at this code:
uShort a = 45;
uShort * ipa = new uShort; /// ipa = new ushort
ipa = &a; /// ipa is now = &a, new ushort is lost forever
*ipa = 100; /// a = 100
you are trying to delete a, and not your new uShort. You don't need to use new on every pointer, only pointers where you need to create some memory. Change your code to:
uShort a = 45;
uShort* ipa = NULL;
ipa = &a;
*ipa = 100;
-
February 7th, 2003, 11:08 PM
#5
mwilliamson had the right idea; it looks like you think you need
to use new any time you want to use a pointer and that's not
true. Go get an introductory book and read up on when new is
actually necessary.
Originally posted by doumalc++
Is "ipa = &a;" the reason why I can't delete?
Why would one crash and not the other when they only differ in the macro?
Basically, you were calling delete on a pointer that hadn't been
new'ed as you alluded to in your question above and mwilliamson
confirmed. When you call delete on a pointer that hasn't been
new'ed, you get undefined behavior. This means that you
MAY get a crash ... but you may just get the program to finish.
You don't know WHAT's going to happen. It's common to get a
crash, but that's not a forgone conclusion.
--Paul
-
February 7th, 2003, 11:38 PM
#6
Originally posted by doumalc++
I am trying to delete "ipa", which is a pointer I created with "new".
You didn't "create" the pointer. The pointer is already created when you declared it. What you did do was to point the pointer somewhere. You pointed it to memory that was allocated with "new". The way it works is that the memory address that you pointed to with "new" must be the same memory address that you point to when you use "delete". You changed what ipa pointed to after you called "new", therefore it isn't the same memory.
Is "ipa = &a;" the reason why I can't delete?
Why would one crash and not the other when they only differ in the macro?
Good question, and it was nicely answered by Paul W. Your program is ill-formed and will introduce undefined behavior. Many programs that seem to work fine are really not. An example is your second program that you said doesn't crash. Here is an example:
Code:
int main()
{
char *p = "ABC123";
p[0] = 'X'; // Bumpy ride here, depending on the compiler
p[6] = 'Z'; // Bumpy ride here, depending on the compiler
return 0;
}
Do you see what's wrong with the program? It is attempting to change a string constant, and it overwrites the memory boundary. This program compiles on every single C++ compiler that I know of. The resulting executable program runs in VC 5.0, VC 6.0. On Solaris, it gets a segmentation fault. Changing a string as I am trying to do is undefined behavior. Note that since the behavior is undefined, I can't guarantee that it will or won't work for your system.
Therefore, the correctness of a C++ program is not determined solely by whether it runs, but whether the constructs used in the program do not introduce undefined behavior, and deleting memory that was not "newed" is such an example.
Regards,
Paul McKenzie
-
February 8th, 2003, 01:03 AM
#7
Thanks guys.
I am enlightened. 
I started learning c++ a month ago on my own. I guess I've got a long way to go. I am going to get more books.
What a bumpy road to mastering c++!
-
February 8th, 2003, 01:11 AM
#8
Originally posted by Paul McKenzie
Here is an example:
Code:
int main()
{
char *p = "ABC123";
p[0] = 'X'; // Bumpy ride here, depending on the compiler
p[6] = 'Z'; // Bumpy ride here, depending on the compiler
return 0;
}
Do you see what's wrong with the program? It is attempting to change a string constant, and it overwrites the memory boundary.
Honestly, I do see (I think) why "p[6] = 'z';" is a problem. How is it so for "p[0] = 'X';"?
Therefore, the correctness of a C++ program is not determined solely by whether it runs, but whether the constructs used in the program do not introduce undefined behavior, and deleting memory that was not "newed" is such an example.
Regards,
Paul McKenzie
Good to know.
-
February 8th, 2003, 03:50 AM
#9
Code:
char *p = "ABC123";
By definition, "ABC123" is a string literal constant. Since it is a constant, it cannot be changed. When you say p[0] = 'X', you are attempting to change the literal, which is not guaranteed to work. Here it is from Stroustrup's "The C++ Programming Language" section 5.2.2
A string literal can be assigned to a char *...It is, however, an error to modify a string literal through such a pointer:
Code:
void f() {
char *p = "Plato";
p[4] = 'e';
}
This kind of error cannot in general be caught until run-time, and implementations differ in their enforcement of this rule.
Try it on a Unix system. More than likely, you'll get a segmentation fault. This bug is one of the most common that Windows programmers discover very early when they attempt to port a Windows C or C++ program to the Unix environment.
The proper way to do this is to declare a proper array of characters:
Code:
char p[] = "ABC123";
p[0] = 'X'; // OK
Regards,
Paul McKenzie
-
February 8th, 2003, 03:52 PM
#10
"The C++ Programming Language"
I've got to read that one.
Reading "Thinking in C++" right now.
Thanks!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|