对数组 C++ 使用删除关键字

Posted

技术标签:

【中文标题】对数组 C++ 使用删除关键字【英文标题】:Using A Delete Keyword With Arrays C++ 【发布时间】:2013-12-23 22:31:36 【问题描述】:

因此,在我的程序中添加了另一个功能,我决定包含一个功能,您可以在其中删除 myCourses[10] 中的所有信息。最新代码:

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

using namespace std;

struct Course

    string name;
    double grade;
    int block;
;

Course enter_course()

    Course foo;

    cout << "What is the name of the course you wish to enter? (Use this format: ExampleFormat)\n";
    cin >> foo.name;
    cout << "What block is " << foo.name << " ?\n";
    cin >> foo.block;
    cout << "What is your current grade as a percent?\n";
    cin >> foo.grade;

    return foo;


void display_courses(Course courseList[10], int courseCount)

    for (int i=0; i<courseCount; i++)
        cout << i+1 << "\t" << courseList[i].name 
             << "\t\tBlock: " << courseList[i].block
             << "\tGrade: " << courseList[i].grade << "%" << endl;
    


double get_gpa(Course courseList[10], int courseCount)

    double gradePoints;
    double total = 0.0;
    for (int i=0; i<courseCount; i++)
        if (courseList[i].grade < 100)
            gradePoints = 4;
         
        if (courseList[i].grade < 90)
            gradePoints = 3;
        
        if (courseList[i].grade < 80)
            gradePoints = 2;
        
        if (courseList[i].grade < 70)
            gradePoints = 1;
        
        if (courseList[i].grade < 60)
            gradePoints = 0;
        
        total += gradePoints;
    

    return total*1.0/courseCount;



void display_options()

    cout << "1. Exit\n";
    cout << "2. Enter a Course\n"; 
    cout << "3. Display Courses\n";
    cout << "4. Display GPA\n";
    cout << "5. Request a text file output\n";
    cout << "6. Delete Grades\n";

    cout << "\n\n";


int main()

    bool exit=0;
    int option;
    int courseCount=0;
    Course myCourses[10]; //nobody should ever take more than 10 courses! 

    while (exit == 0)
    
        cout << "GradeBook 2.0\n";
        display_options();
        cout << "Enter a command.\n";
        cin >> option;

        switch (option)
        
            case 1: 
                exit = 1;
                break;
            case 2:
                myCourses[courseCount] = enter_course();
                courseCount++;
                break;
            case 3:
                display_courses(myCourses, courseCount);
                break;
            case 4:
                cout << get_gpa(myCourses, courseCount) << endl;
                break;
            case 5:
                ofstream outputFile;
                outputFile.open("userGrades.txt");
                for (int i = 0; i < courseCount; i++)
                
                    outputFile << myCourses[i].name << " " << myCourses[i].grade << " " << myCourses[i].block << endl;
                
                outputFile.close();
                cout << "Grades saved to file!" << endl;
                break;
            case 6:
                cout << "Removing data...\n";
                delete[] myCourses;
                break;
        
    

    return 0;

但是,我收到以下错误: 错误 C2360:“case”标签跳过了“outputFile”的初始化(第 114 行) IntelliSense:控制转移绕过初始化:变量“outputFile”(在第 105 行声明)(第 89 行) 警告 C4154:删除数组表达式;转换为提供的指针(第 116 行) 有谁知道在 switch 块中使用 delete[] 关键字有什么问题?

【问题讨论】:

【参考方案1】:

问题是您尝试delete 不是您使用new 创建的东西。也就是说,数组myCourses 不是动态分配的。你用new动态分配一些东西,然后用delete释放它。如果你不动态分配它,你就让它超出范围。

只需去掉 delete[] myCourses; 行。

您不能从数组中删除元素。它们从声明数组的那一刻起一直存在,直到它超出范围。如果您希望元素具有某种清除状态,则需要确定它是什么。例如,您可以给Course 一个标志,说明它是否已清除。但是,更好的方法是使用像 std::vector 这样的标准库容器 - 这样,您就可以真正从中删除元素。

您的另一个错误是由于试图在 switch 语句中声明一个变量而没有将它包含在它自己的块中。您可以通过在 case 5: 的内容周围放置花括号来解决此问题。

【讨论】:

我宁愿称这个问题为“猜测编程”。拿一堆你在别处见过但还没有真正理解的语法,把它们混合在一起,祈祷能出现一些功能性的东西。如果没有,请在 SO 上发布。 @KerrekSB 这就是所谓的“cargo cult programming”,根据人们看到装满食物和补给品的飞机降落在机场并建造自己的复制机场、收音机和跑道的故事,他们期待着装满金属鸟的金属鸟食物和补给也会出现在他们面前。 @sftrabbit 那么我该如何实现std::vector呢?我在参考网站上找不到它。 @DavidSchwartz:嗯,不完全是。 Cargo cult 编程会产生正确但糟糕或无意义的代码。我认为这个更深刻,因为 OP 对语言的工作原理没有一个清晰的概念,而是试图动摇它,直到它做一些有用的事情。 @KerrekSB 货物崇拜编程的本质是你在你的代码中撒上你看到其他人使用的东西,希望你能得到与他们一样的效果。例如,如果您有内存泄漏,请在代码中添加deletes。如果你有竞争条件,你可以在周围撒上volatiles 和互斥锁。【参考方案2】:

你不能delete 你没有new。他们必须对应。您正在尝试 delete 一个从未使用 new 分配的对象。

【讨论】:

那么有没有更好的关键字可以放在那里? @DJHead-On 该行应该一起消失。 @sftrabbit 但是有没有我可以写的东西来代替预期的目的? @DJHead-On 阵列具有固定大小。您无法从中清除元素。相反,您应该使用std::vector。互联网上有大量关于std::vector 的信息。 @sftrabbit 我查了std::vector,但我似乎不知道如何使用它。【参考方案3】:

由于其他人已经评论了不明智的delete[],让我们也解决另一个问题:如果您想在switch-statement 的块内构造一个对象,您需要将它放入它自己的块中:

switch (option)

    case 5:
        
            ofstream outputFile;
            outputFile.open("userGrades.txt");
            for (int i = 0; i < courseCount; i++)
            
                outputFile << myCourses[i].name << " " << myCourses[i].grade << " "
                           << myCourses[i].block << endl;
            
            outputFile.close();
            cout << "Grades saved to file!" << endl;
            break;
        
    

(请注意围绕std::ofstream 的块周围的额外括号)。另外,请注意,不必要地使用std::endl 会导致性能问题!除非您真的要刷新流,否则请改用'\n'。 ...当您要刷新流时,请使用 std::flush 而不是使用 std::endl 隐藏它。

【讨论】:

以上是关于对数组 C++ 使用删除关键字的主要内容,如果未能解决你的问题,请参考以下文章

C++ 数组和“new”关键字

(C++)堆排序的3个关键函数

c++ STL 迭代器失效问题

删除视频的某些部分并重新制作关键帧(c++ + libav)

一百万个结构数组,根据其中一项值排序,用双链表还是数组排序效率更好,请给出最快C或C++算法代码。

C++中const关键字的使用总结