Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;这个函数会泄漏吗?_C++_Memory Leaks - Fatal编程技术网

C++ C++;这个函数会泄漏吗?

C++ C++;这个函数会泄漏吗?,c++,memory-leaks,C++,Memory Leaks,我开始写一个简单的游戏机Yahtzee来练习。我只是有一个关于这个函数是否会泄漏内存的问题。每次需要重新掷骰子时都会调用roll函数 它所做的是创建一个动态数组。第一次使用时,它将存储5个随机值。对于下一次运行,它只会重新滚动除您想要保留的骰子以外的所有骰子。我还有另外一个函数,但是因为它与这个问题无关,所以我把它省略了 主要功能 int *kast = NULL; //rolled dice int *keep_dice = NULL; //which dice to

我开始写一个简单的游戏机Yahtzee来练习。我只是有一个关于这个函数是否会泄漏内存的问题。每次需要重新掷骰子时都会调用roll函数

它所做的是创建一个动态数组。第一次使用时,它将存储5个随机值。对于下一次运行,它只会重新滚动除您想要保留的骰子以外的所有骰子。我还有另外一个函数,但是因为它与这个问题无关,所以我把它省略了

主要功能

int *kast = NULL;           //rolled dice
int *keep_dice = NULL;    //which dice to re-roll or keep

kast = roll(kast, keep_dice);
delete[] kast;
这是函数

int *roll(int *dice, int *keep) {

    srand((unsigned)time(0));
    int *arr = new int[DICE];
    if(!dice)
    {
        for(int i=0;i<DICE;i++)
        {

            arr[i] = (rand()%6)+1;
            cout << arr[i] << " ";
        }
    }
    else
    {
        for(int i=0;i<DICE;i++)
        {
            if(!keep[i])
            {
                dice[i] = (rand()%6)+1;
                cout << "Change ";
            }
            else
            {
                keep[i] = 0;
                cout << "Keep ";
            }
        }
        cout << endl;
        delete[] arr;
        arr = NULL;
        arr = dice;

    }
    return arr;
}
int*roll(int*dice,int*keep){
srand((未签名)时间(0));
int*arr=新的int[DICE];
如果(!骰子)
{

对于(int i=0;i使用(堆栈分配的)
std::vector
而不是数组,并将对它的引用传递给函数。这样,您就可以确保它不会泄漏。

是的,它可能泄漏。例如,使用
cout
会引发异常,如果发生,则永远不会调用
delete

<> P>而不是自己分配一个动态数组,您可能需要考虑返回一个<代码> STD::vector < /代码>。更好的是,将您的函数转换成一个适当的算法,该算法使用一个迭代器(在这种情况下,是一个<代码> BuffiStIdTyTyrase<代码>),并将它的输出写入那里。 编辑:更仔细地看,我觉得有必要指出,我真的非常不喜欢这段代码的基本结构。你有一个函数实际上做两种不同的事情。你还有一对数组,你依赖于并行寻址。我将它重组成两个独立的函数,一个
roll
重新滚动
。我将数据重新构造为结构数组:

struct die_roll { 
    int value;
    bool keep;

    die_roll() : value(0), keep(true) {}
};

要进行初始滚动,您需要传递一个向量(或者数组,如果您确实坚持的话)要进行重新滚动,将向量传递给
re roll
,该向量将重新滚动,以便为
keep
成员已设置为
false
的任何模具滚动获取新值。分配内存的方式令人困惑:函数内分配的内存必须是f函数外部的代码

为什么不把它改写成这样:

int *kast = new int[DICE];           //rolled dice
bool *keep_dice = new bool[DICE];    //which dice to re-roll or keep
for (int i = 0; i < DICE; ++i)
    keep_dice[i] = false;

roll(kast, keep_dice);

delete[] kast;
delete[] keep_dice;

<>也应该把<代码> SRAND <代码>调用到程序的开始。重新播种对随机性非常有害。

< P>我建议你花时间去购买/借用和阅读Scott Meyers有效C++第三版。你将节省自己几个月的痛苦,成为一个有生产力的C++程序员。个人的痛苦体验。

或者,使用
自动\u ptr
是有益的。Sry没有提到这些cout仅用于错误检查。无论如何,除此之外,功能防泄漏和数组删除是否正确?@klw:是的,只要您确保在分配和释放内存之间不会引发异常,您的代码应该没有内存泄漏。但是,这种情况意味着您的代码(并非双关语)最脆弱。@Travis:您最好不要使用
auto_ptr
new[]分配的内存在特拉维斯中,函数不是“异常容忍”的。这是C++中的坏设计,意味着任何人在修改代码之后都会措手不及(因为他们希望作者或以前的维护者能够胜任,而不编写在异常情况下是危险的代码)。还提供了一个公开原始指针的接口,其意图是含糊不清的。没有任何迹象表明,您是否正在通过函数声明传递所有权或保留所有权(C++中,这是不好的,因为我们有一个所有权语义的主要问题)。有人告诉过你在删除指针后总是为指针分配NULL吗?他们错了。
arr=NULL;arr=dice;
相当多余。:]如果你构建时只启用了第一级优化,那么这一行就不会存在于编译输出中。(
arr=NULL;
)@史蒂夫:我记得在书中读到过关于它的内容。是什么让它错了?我认为这只是出于安全考虑。@klw:虽然删除后为指针指定NULL并不是特别有害,但在你的:
arr=NULL;arr=dice;
这样的情况下,它也是毫无意义的。试着想出一个好的理由怎么样?@jason:如果“安全"你的意思是让坏代码运行。当然,对于我自己来说,如果我删除了一些东西,我希望我的程序崩溃。但是,在这种情况下,它绝对是没有意义的,因为它后来被重新分配了一个语句。我已经考虑使用向量,但是既然我已经知道我想要的大列表,我认为使用数组会更好。@ KW:什么?at没有意义。标准的、更安全的代码版本是
std::vector
,知道大小没有意义,只需对向量调用
resize
reserve
。事实上,如果您使用了正确的构造函数,因此不需要重新分配,您就不会为此支付费用。它可能与数组一样快,而且更容易的是,KLW:FYA,GCC和下一个C++标准的最新版本将有STD::数组ARR;它会做你想要的。其他的评论者严格来说是错误的;向量动态地分配它的数组,这有时是不需要的,甚至有时是不可能的。hough;如果你在一个完整的操作系统上开发一个应用程序,vector可能很好。@Tim据我所知,每个人都推荐vector而不是动态数组,因此已经有了分配。
void roll(int *dice, int *keep) {
    for(int i=0;i<DICE;i++)
    {
        if(keep[i])
        {
            keep[i] = false;
            cout << "Keep ";
        }
        else
        {
            dice[i] = (rand()%6)+1;
            cout << "Change ";
        }
    }
    cout << endl;
}