【问题标题】:loop for with class functions error when condition too high当条件太高时循环使用类函数错误
【发布时间】:2014-04-05 15:42:39
【问题描述】:

上次我在使用 for 循环时经常出错。

最简单的展示方式是:

#include <iostream>
class Class
{
private:
    int number;
public:
    Class(int a);
    void get();
};

Class::Class(int a)
{
    number=a;
}

void Class::get()
{
    std::cout<<number<<std::endl;
}

int main()
{
    int amount=4;
    Class* p[amount];
    for(int i=0;i<amount;i++)
    {
        delete p[i];
        p[i]=new Class(i);
    }
    for(int i=0;i<amount;i++)
    {
        p[i]->get();
    }
    return 0;
}

程序返回 255,在调试时我收到 SIGSEGV 信号 - 分段错误。

我发现一件很奇怪的事情:当amount=3 或更少的程序正常工作时。我打算将它用于 700 多个元素,所以我发现这非常令人失望。

我正在使用带有 GNU GCC 编译器的 Windows 7 和 Code::Blocks 13.12。

我应该在此程序中进行哪些更改以使其正常运行?我很确定这只是我对 c++ 或类似东西的一点了解。

提前致谢。

【问题讨论】:

  • 您应该知道Class* p[amount];amount 不是编译时间常数时是gcc 编译器扩展,并且不是C++ 语言规范的一部分。

标签: c++ class for-loop segmentation-fault


【解决方案1】:
Class* p[amount];
for(int i=0;i<amount;i++)
{
    delete p[i];
    p[i]=new Class(i);
}

您应该删除delete p[i]; 行,因为数组p 尚未初始化。

【讨论】:

    【解决方案2】:

    您一直在对不指向动态分配对象的指针调用delete

    Class* p[amount]; // array of uninitialized pointers
    
    delete p[i]; // oops
    

    【讨论】:

    • 如我所说。只是我的无知......谢谢大家
    【解决方案3】:

    这是怎么回事(见 cmets):

    // This allocates `amount` spots for pointers
    Class* p[amount];
    // Your pointers are not initialized yet
    for(int i=0;i<amount;i++)
    {
        // You are trying to delete what they point to
        delete p[i]; // <<== This is undefined behavior
        p[i]=new Class(i);
    }
    

    在分配要删除的对象之前,您不应调用delete。否则,这是未定义的行为,即您的程序可能会崩溃。

    最后,您需要在完成后删除指针以避免内存泄漏。您可以为此使用智能指针向量(推荐),或者简单地将另一个循环添加到您的程序中,如下所示:

    int amount=4;
    Class* p[amount];
    for(int i=0;i<amount;i++)
    {
        p[i]=new Class(i);
    }
    for(int i=0;i<amount;i++)
    {
        p[i]->get();
    }
    for(int i=0;i<amount;i++)
    {
        delete p[i];
    }
    

    【讨论】:

    • delete(0) 没问题,Class* p[amount] = {} 会修复它
    • @DieterLücking 感谢您的评论!尽管这肯定是正确的,但在首次使用之前删除某些内容是没有意义的。 OP 听起来像是一个初学者的 C++ 程序员,所以我宁愿不教她一些她一开始就不应该做的事情。
    【解决方案4】:

    初始化 p[i] 和声明。 类* p[3] = {0}; delete 内置了 null 检查,因此您不会收到任何错误

    即使数量为 3 或小于 3,您也应该得到错误

    【讨论】:

    • 删除指向无效内存位置的指针会导致未定义的行为,因此可能会导致错误,也可能不会,没有“应该”。
    • @Oktalist 同意,但是对于少于 3 个没有问题并且超过 3 个总是分段错误,它不能保持一致。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-27
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-11
    相关资源
    最近更新 更多