-11

As I've read on cpprefrence:

Delete Deallocates storage previously allocated by a matching operator new.

But here, I only get 3.4 as an output and not 2.1.

#include <iostream>
int main(){
    float x, y; x = y = 0;
    float * p = &x;
    *p = 3.4;
    std::cout << *p;
    delete p; //Can I deallocate memory of a static pointer?
    p = &y;
    *p = 2.1;
    std::cout << *p;
    delete p;
    return 0;
}

UPDATE: I've added operator new here and the code doesn't give the expected results still.

int main(){
    float *p = new float(3.4);
    float x, y; x = y = 0;
    p = &x;
    *p = 3.4;
    cout << *p;
    delete p; //Deallocate the memory of p pointer.
    p = &y; //Shouldn't this line reallocate the memory to p? or maybe &p = &y;
    *p = 2.1;
    cout << *p;
    delete p;
    return 0;
}

We were told by our teacher to find a workaround to still be able to set a value for where the pointer is pointing at after deleting the poitner

int main(){
    float *p = new float(3.4);
    delete p; // We want to delete the pointer but change the value of *p afterwards.
    *p = 2.1;
    std::cout << *p;
}
Shayan
  • 709
  • 1
  • 15
  • 31
  • 7
    `delete p;` is cause for undefined behavior. Don't count on anything after that. – R Sahu Jan 04 '18 at 19:09
  • @RSahu Oh wait I have searched for questions like this and I've seen Undefined Behaviour, I DON'T KNOW WHAT IT MEANS – Shayan Jan 04 '18 at 19:10
  • 4
    [Undefined, unspecified and implementation-defined behavior](https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior). – R Sahu Jan 04 '18 at 19:10
  • @Shayan It means, that the behavior of your program is undefined. It can do what you expect, it can crash, or it can cause your computer to catch fire. – Algirdas Preidžius Jan 04 '18 at 19:11
  • 3
    You `delete` what you `new`, and `delete[]` what you `new[]`. If you haven't used `new` or `new[]` you should not use `delete` or `delete[]`. – Some programmer dude Jan 04 '18 at 19:12
  • I added `float *p = new float(3.14);` to the beginning of the code, it doesn't even run now, any idea? – Shayan Jan 04 '18 at 19:13
  • As your quote says, no deleting anything unless it was allocated with `new`, otherwise your misusing the operator and "anything could happen". That's what "undefined behavior" means. – erik258 Jan 04 '18 at 19:13
  • TL;DR version: Undefined behaviour means the C++ standard does not specify what will happen. The program may do what you expect. It might do what you expect sometimes. It may never do what you expect. It may crash. It may produce subtly incorrect results. It may do different things at different times. It may trigger mocking laughter from the computer's speakers and a shower of unicorns and glitter. – user4581301 Jan 04 '18 at 19:14
  • @DanFarrell So there's no way to make this work w/o `new` interesting... because I pasted the actual code from a CPP BOOK... – Shayan Jan 04 '18 at 19:15
  • How many `new` do you have? How many `delete`? If you have `delete` without a matching `new` then you're right back at where you started. – Some programmer dude Jan 04 '18 at 19:15
  • @Shayan 1) It's unclear what do you mean by "_beginning of the code_", since it's unclear what do you consider to be the "_beginning_" of it. [Edit] your question to include [mcve]. 2) "_because I pasted the actual code from a CPP BOOK_" If you found such a code in a book, and the intention of a chapter isn't meant to show what **not** to do, throw it away, and get a [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) instead. – Algirdas Preidžius Jan 04 '18 at 19:15
  • You aren't using new or delete right here. Read https://www.geeksforgeeks.org/new-and-delete-operators-in-cpp-for-dynamic-memory/ – erik258 Jan 04 '18 at 19:16
  • 1
    @Shayan Are you saying the book advises calling `delete` on an automatic storage? If so, burn it. – George Jan 04 '18 at 19:16
  • @George Yes, that's what I said – Shayan Jan 04 '18 at 19:17
  • 2
    @Shayan Sure, you allocate some `float`, but it's not *that float* you are deleting, it's still `x` because you changed `p` to point to `x` and lost all handles to the newly allocated one (leaked it). – François Andrieux Jan 04 '18 at 19:17
  • 1
    @Shayan Your updated code invokes undefined behavior for the same reason. Since the pointer, which you got from `new` is being overwritten in `p = &x;` statement, and you are still invoking `delete` on the pointer to automatic variable. – Algirdas Preidžius Jan 04 '18 at 19:18
  • 3
    Please let us know which book. Odds are someone will be familiar with it and can either point you at an errata sheet or explain the point the writer of the text was trying to make. – user4581301 Jan 04 '18 at 19:19
  • 1
    @Shayan *delete p; // I need to delete p right at this part of code.* -- In your own words, define what "delete" means to you. Does "delete" mean the code crashes? A message box pops up saying "you did something wrong"? The pointer disappears in thin air like a magic trick? It was stated already that you can do all kinds of stupid stuff with pointers, including accessing pointers that point to invalid memory. C++ does not stop you from doing this. It's your responsibility that your code isn't doing the stupid stuff. – PaulMcKenzie Jan 04 '18 at 20:17
  • @user4581301 Our teacher opens her book and starts lessons from that book, so I knew if there was something wrong it had to be because of the book but no, I got the book and I didn't find this argument, this question is because of the misconception our teacher had about `delete`. – Shayan Feb 16 '18 at 12:05

2 Answers2

3

From your post:

Delete Deallocates storage previously allocated by a matching operator new.

When you use:

float x, y; x = y = 0;
float * p = &x;
delete p;

you are not following that statement.

p does not point to an object that was allocated by operator new. It points to a local variable on the stack.

With your updated code, you did allocate memory by calling new but you changed p so that it points to a variable on the stack.

float *p = new float(3.4);  // p points to object returned by new
float x, y; x = y = 0;
p = &x;                     // p points to x. The previous memory is leaked

Consequently,

  1. Your program has a memory leak.
  2. Your program is still subject to undefined behavior when it executes delete p;.

What's the solution to fixing the following code.

Solution 1 Don't use p after the line delete p; as though it is a valid pointer since it is not.

Solution 2 Allocate new memory, assign it to p and use p only after that.

int main(){
  float *p = new float(3.4);
  delete p; // I need to delete p right at this part of code.

  p = new float; // Allocate new memory
  *p = 2.1;
  std::cout << *p;
  delete p;      // Deallocate the memory before program ends
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • So my understanding is that, First, I won't be able to delete the memory created by new after I do `p= &x` and Second, I should not be changing where the pointer p is pointing from new to x with `p = &x` and Third, What's the solution to the REAL problem (Edited question) – Shayan Jan 04 '18 at 19:31
  • @Shayan The "REAL problem" is an entirely different one. In that case, you are using a deleted object. – François Andrieux Jan 04 '18 at 19:34
  • @FrançoisAndrieux There's a bit of mistranslation so bear with me, In the REAL problem, is the `p` pointer a wandering pointer? From the book I'm reading, it says, a wandering pointer is a pointer which doesn't point anywhere, and thus the code in REAL problem part of my question doesn't run, so the book, gives a solution to fix the issue and that's my first code in the question. – Shayan Jan 04 '18 at 19:38
  • 1
    @Shayan, do they use "wandering pointer" or "dangling pointer"? – R Sahu Jan 04 '18 at 19:41
  • @RSahu Yes what I mean is "Dangling Pointer". – Shayan Jan 04 '18 at 19:44
  • @RSahu I just googled about dangling pointer, and I can see that a dangling pointer is a pointer which points to something that doesn't exist anymore (is invalid) and in my code (after REAL problem) after `delete p;`, p will not be a dangling pointer, so if it's not a dangling pointer then what is it? – Shayan Jan 04 '18 at 19:55
  • 1
    @Shayan, it is a dangling pointer after `delete p;`. That's the most succinct way to define a dangling pointer. – R Sahu Jan 04 '18 at 19:57
  • @RSahu Can you take a look at where I edited the question and added comment `p = &y; //Shouldn't this line reallocate the memory to p?` I was thinking `p=&y` reallocates memory to p, but in order to reallocate memory can I do `&p = 100` (100 is a random number) – Shayan Feb 16 '18 at 12:13
  • 1
    @Shayan, neither. Using the `&` operator does not allocate memory. It simply evaluates the address of a variable. .Consequently, `&100` is not a valid expression. To allocate memory, you'll have to use `p = new int(y);` or `p = new int(100);`. – R Sahu Feb 16 '18 at 16:16
0

You are trying to delete automatically allocated variables (usually in the stack). Operator delete is meant to be applied only on dynamically allocated variables (usually in the heap). There are libs for stack memory management, but it is a good practice to let your compiler unstack by itself all automatically allocated variables each time they go out of scope.

Jango
  • 378
  • 4
  • 8
  • 1
    Recommend replacing stack and heap with Automatic and Dynamic storage as stacks and heaps are implementation-level concepts and may not be present. That said, you can go through an entire programming career and never see anything but stacks and heaps. – user4581301 Jan 04 '18 at 19:28
  • I agree and have updated the answer, although I think those concepts are still indispensable since they are (were?) the most used way to implement allocation in the history of C and C++. – Jango Jan 04 '18 at 19:55
  • 1
    Stack and Heap still are dominant. Only systems I've seen that weren't stack and heap were academic or "Because I could." and I don't think I wrote non-toy code for any of them. – user4581301 Jan 04 '18 at 20:04