简体   繁体   English

为什么删除指针不能正常工作?

[英]Why isn't delete pointer working properly?

I have a problem, that I created a pointer using int *w = new int;我有一个问题,我使用int *w = new int;创建了一个指针。 and I wanted to delete it delete w;我想删除它delete w; after switch case loop.在切换案例循环之后。 However I get the error shown in the attached screenshot.但是,我收到了所附屏幕截图中显示的错误。 What is interesting, delete w;有什么有趣的, delete w; works only before pointer references to the address of the object in vector: w = &products.at(i).inStock;仅在指向向量中 object 的地址的指针引用之前有效: w = &products.at(i).inStock; . . After that, I get error.之后,我得到错误。 The delete w; delete w; also works if i set w = NULL;如果我设置 w = NULL; , what makes no sense to me. ,什么对我来说毫无意义。 Please help.请帮忙。

vendingmachine.h自动售货机.h

#pragma once
#define MAX_PRODUCTS_STOCK 10
#define FIVEBUCKS_DEFAULT_STOCK 1
#define TWOBUCKS_DEFAULT_STOCK 5
#define ONEBUCK_DEFAULT_STOCK 10
#define FIFTYPENNY_DEFAULT_STOCK 10
#define TWENTYPENNY_DEFAULT_STOCK 50
#define TENPENNY_DEFAULT_STOCK 100

#include<iostream>
#include<string>
#include<vector>
#include<fstream>

using namespace std;
//all classes below using namespace std

class VendingMachine
{
public:

    string name;
    int inStock;
    double value; //in Product the value is price, in Money the value is value
    int index;

    void loadFromFile(string ftxt);
    virtual void display() = 0; //clear virtual function, that will ve overridden in both Money and Product classes
    void saveToFile(string ftxt);

};

vendingmachine.cpp自动售货机.cpp

#pragma once
#define MAX_PRODUCTS_STOCK 10
#define FIVEBUCKS_DEFAULT_STOCK 1
#define TWOBUCKS_DEFAULT_STOCK 5
#define ONEBUCK_DEFAULT_STOCK 10
#define FIFTYPENNY_DEFAULT_STOCK 10
#define TWENTYPENNY_DEFAULT_STOCK 50
#define TENPENNY_DEFAULT_STOCK 100

#include<iostream>
#include<string>
#include<vector>
#include<fstream>

#include"vendingmachine.h"

using namespace std;
//all classes below using namespace std

void VendingMachine::loadFromFile(string ftxt)
{
    fstream file;
    file.open(ftxt, ios::in);

    if (file.good() == false)
    {
        cout << "Unable to load the file. Try again later." << endl;
        file.close();
        exit(0);
    }
    else
    {
        int indexLineNr = (index - 1) * 4 + 1;
        int currentLineNr = 1;
        string lineText; //text gathered from one line in the text file
        while (getline(file, lineText)) //read the file till there is anyhting to read
        {
            if (currentLineNr == indexLineNr)
            {
                name = lineText.substr(3);
            }
            if (currentLineNr == indexLineNr + 1)
            {
                inStock = stoi(lineText.substr(8));
            }
            if (currentLineNr == indexLineNr + 2)
            {
                value = stod(lineText.substr(7, 5));
            }
            if (currentLineNr == indexLineNr + 3)
            {

            }
            /*currentLineNr++;*/
            currentLineNr++;
        }

        file.close();
    }
}

void VendingMachine::saveToFile(string ftxt)
{
    fstream file;

    file.open(ftxt, ios::out | ios::app);

    file << index << ") " << name << endl
        << "Amount: " << inStock << endl;

    file.close();
}

money.h钱.h

#pragma once
#define MAX_PRODUCTS_STOCK 10
#define FIVEBUCKS_DEFAULT_STOCK 1
#define TWOBUCKS_DEFAULT_STOCK 5
#define ONEBUCK_DEFAULT_STOCK 10
#define FIFTYPENNY_DEFAULT_STOCK 10
#define TWENTYPENNY_DEFAULT_STOCK 50
#define TENPENNY_DEFAULT_STOCK 100

#include<iostream>
#include<string>
#include<vector>
#include<fstream>

#include"vendingmachine.h"

using namespace std;

//all classes below using namespace std

class Money : public VendingMachine
{
    string filename = "money.txt";

public:

    Money(int = 1, string = "Money", int = 0, double = 0.0);

    virtual void display();
    void saveMoneyToFile(string ftxt);
};

money.cpp钱.cpp

#define MAX_PRODUCTS_STOCK 10
#define FIVEBUCKS_DEFAULT_STOCK 1
#define TWOBUCKS_DEFAULT_STOCK 5
#define ONEBUCK_DEFAULT_STOCK 10
#define FIFTYPENNY_DEFAULT_STOCK 10
#define TWENTYPENNY_DEFAULT_STOCK 50
#define TENPENNY_DEFAULT_STOCK 100

#include<iostream>
#include<string>
#include<vector>
#include<fstream>

#include"money.h"

using namespace std;

//all classes below using namespace std

Money::Money(int id, string n, int a, double v) //index, name, inStock, value (value)
{
    index = id;
    name = n;
    inStock = a;
    value = v; //in Product the value is price, in Money the value is value
}

void Money::display()
{
    cout << index << ") " << name << endl
        << "Amount: " << inStock << endl
        << "Value: " << value << " PLN " << endl
        << endl;
}

void Money::saveMoneyToFile(string ftxt)
{
    VendingMachine::saveToFile(ftxt);
    fstream fadd;
    fadd.open(ftxt, ios::out | ios::app);
    fadd << "Value " << value << " PLN" << endl
        << endl;
    fadd.close();
}

products.h产品.h

#pragma once
#define MAX_PRODUCTS_STOCK 10
#define FIVEBUCKS_DEFAULT_STOCK 1
#define TWOBUCKS_DEFAULT_STOCK 5
#define ONEBUCK_DEFAULT_STOCK 10
#define FIFTYPENNY_DEFAULT_STOCK 10
#define TWENTYPENNY_DEFAULT_STOCK 50
#define TENPENNY_DEFAULT_STOCK 100

#include<iostream>
#include<string>
#include<vector>
#include<fstream>

#include"vendingmachine.h"

using namespace std;

//all classes below using namespace std

using namespace std;

class Product : public VendingMachine
{
    string filename = "products.txt";

public:
    Product(int = 1, string = "Product", int = MAX_PRODUCTS_STOCK, double = 0.0);

    virtual void display();
    void saveProductsToFile(string ftxt);
};

products.cpp产品.cpp

#define MAX_PRODUCTS_STOCK 10
#define FIVEBUCKS_DEFAULT_STOCK 1
#define TWOBUCKS_DEFAULT_STOCK 5
#define ONEBUCK_DEFAULT_STOCK 10
#define FIFTYPENNY_DEFAULT_STOCK 10
#define TWENTYPENNY_DEFAULT_STOCK 50
#define TENPENNY_DEFAULT_STOCK 100

#include<iostream>
#include<string>
#include<vector>
#include<fstream>

#include"products.h"
//#include"vendingmachine.h"

using namespace std;

//all classes below using namespace std

Product::Product(int id, string n, int a, double v) //index, name, inStock, value (price)
{
    index = id;
    name = n;
    inStock = a;
    value = v; //in Product the value is price, in Money the value is value
}

void Product::display()
{
    cout << index << ") " << name << endl
        << "Amount: " << inStock << endl
        << "Price: " << value << " PLN " << endl
        << endl;
}

void Product::saveProductsToFile(string ftxt)
{
    VendingMachine::saveToFile(ftxt);
    fstream fadd;
    fadd.open(ftxt, ios::out | ios::app);
    fadd << "Price: " << value << " PLN" << endl
        << endl;
    fadd.close();
}

main.cpp主文件

#define MAX_PRODUCTS_STOCK 10
#define FIVEBUCKS_DEFAULT_STOCK 1
#define TWOBUCKS_DEFAULT_STOCK 5
#define ONEBUCK_DEFAULT_STOCK 10
#define FIFTYPENNY_DEFAULT_STOCK 10
#define TWENTYPENNY_DEFAULT_STOCK 50
#define TENPENNY_DEFAULT_STOCK 100

#include<iostream>
#include<string>
#include<vector>
#include<fstream>

#include"vendingmachine.h"
#include"products.h"
#include"money.h"

using namespace std;

double userInput;
double cart;
bool ok = false;

void onDelete(string ftxt)
{
    fstream fdelete;
    fdelete.open(ftxt, ios::out | ios::trunc);
    fdelete.close();
}

int main()
{
    double* wskU;
    Product* wskP;
    Money* wskM;

    cout << "Would you like to come back to the default stock?" << endl
        << "1. Yes, restock all the products and money  2. No, i want to load previous state" << endl;

    cin >> userInput;
    wskU = &userInput;

    // making a vector of default Products
    vector<Product> products;
    for (int i = 0; i < 5; i++)
    {
        products.push_back(Product());
        wskP = &products.at(i);
        wskP->index = i + 1; //index is needed to know from which line in the textfile, new product's members start
        wskP = &products.at(i);
        wskP->loadFromFile("products.txt");
        //wskP->display(); // to check if it works
    }
    //making a vector of default Money
    vector<Money> money;
    for (int j = 0; j < 6; j++)
    {
        money.push_back(Money());
        wskM = &money.at(j);
        wskM->index = j + 1; //index is needed to know from which line in the textfile, new product's members start
        wskM = &money.at(j);
        wskM->loadFromFile("money.txt");
        //wskM->display(); // to check if it works
    }

    // askIfDefault

    int* w = new int;

    while (ok == false)
    {
        switch ((int)round(*wskU))
        {
            // if we want to come back to default stock, all of the products and money members are restored
        case 1:
        {
            /*cout << "CASE 1 " << endl;*/
            for (int i = 0; i < 5; i++)
            {
                w = &products.at(i).inStock;
                *w = MAX_PRODUCTS_STOCK;
                //wskP = &products.at(i);
                //wskP->display();
            }

            w = &money.at(0).inStock;

            *w = FIVEBUCKS_DEFAULT_STOCK;
            /*wskM = &money.at(0);
            wskM->display();*/

            w = &money.at(1).inStock;
            *w = TWOBUCKS_DEFAULT_STOCK;
            /*wskM = &money.at(1);
            wskM->display();*/

            w = &money.at(2).inStock;
            *w = ONEBUCK_DEFAULT_STOCK;
            /*wskM = &money.at(2);
            wskM->display();*/

            w = &money.at(3).inStock;
            *w = FIFTYPENNY_DEFAULT_STOCK;
            /*wskM = &money.at(3);
            wskM->display();*/

            w = &money.at(4).inStock;
            *w = TWENTYPENNY_DEFAULT_STOCK;
            /*wskM = &money.at(4);
            wskM->display();*/

            w = &money.at(5).inStock;
            *w = TENPENNY_DEFAULT_STOCK;
            /*wskM = &money.at(5);
            wskM->display();*/

            cart = 0;
            /*w = NULL;*/
            ok = true;

        }
        break;

        // if we want to load the previous state 
        case 2:
        {
            /*cout << "CASE 2 " << endl;*/
                //wskP->display(); // to check if it works
            cart = 0;
            /*w = NULL;*/
            ok = true;

        }
        break;
        default:
        {
            cout << "Choose one either 1st or 2nd option: " << endl;
        }
        }
    }

    delete w;

    cout << endl << "How may I help you ?" << endl
        << "Choose one of the available products: " << endl
        << endl;

    for (int i = 0; i < 5; i++)
    {
        wskP = &products.at(i);
        wskP->display();
    }
    cout << "6) Go to checkout" << endl << endl
        << "7) Exit" << endl << endl;

    //cin >> userInput;
    //wskU = &userInput;


    //onDelete("products.txt");
    //for (int j = 0; j < 5;j++)
    //{
    //  wskP = &products[j];
    //  wskP->saveProductsToFile("products.txt");
    //}

    //onDelete("money.txt");
    //for (int j = 0; j < 5;j++)
    //{
    //  wskM = &money[j];
    //  wskM->saveMoneyToFile("money.txt");
    //}

    system("pause");
}

enter image description here在此处输入图像描述

In your question you say you "created a pointer using int *w = new int; " But what you did is allocate a new int on the heap and stored the pointer to it in w .在您的问题中,您说您“使用int *w = new int;创建了一个指针”,但是您所做的是在堆上分配一个新的 int 并将指向它的指针存储在w中。 You then change that pointer to point into the money variable.然后,您将该指针更改为指向货币变量。

Now the phrase delete w will tell your compiler to try and delete anything the pointer w is pointing to.现在短语delete w将告诉您的编译器尝试删除指针w指向的任何内容。 To be clear, it is not deleting the pointer itself, only the memory it is pointing to.需要明确的是,它并没有删除指针本身,只是它指向的 memory 。

From what I can see (but I agree with the advice above to create a minimal reproducible example), you can just allocate the pointer on the stack, like this:从我所看到的(但我同意上面创建一个最小可重现示例的建议),您可以在堆栈上分配指针,如下所示:

int *w;

The pointer is then automatically removed as soon as the method ends and you do not need to call delete for that.一旦方法结束,指针就会自动删除,您无需为此调用delete

That said, the whole use of a pointer to change a variable looks like a code smell to me.也就是说,对我来说,整个使用指针来更改变量看起来像是一种代码味道。 Can't you just change the value without pointers, eg:你不能只改变没有指针的值,例如:

products.at(i).inStock = MAX_PRODUCTS_STOCK;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM