1

こんにちは私は次の機能を持っています:

Block* Keywords::parseBlock(TiXmlElement* element)
{
    double x1 = atoi(element->Attribute("left"));
    double y1 = atoi(element->Attribute("top"));
    double x2 = atoi(element->Attribute("right"));
    double y2 = atoi(element->Attribute("bottom"));
    double width  = abs(x2 - x1);
    int bid = atoi(element->Attribute("id"));

    vector<LineElement*> lines;
    for (TiXmlElement* sub = element->FirstChildElement("line"); sub; sub = sub->NextSiblingElement("line"))
        lines.push_back(parseLine(sub));

    return new Block(y2,x2,y1,x1,bid,width, lines);
}///End function parse Block

LineElement* Keywords::parseLine(TiXmlElement* element)
{
    double x1 = atoi(element->Attribute("left"));
    double y1 = atof(element->Attribute("top"));
    double x2 = atoi(element->Attribute("right"));
    double y2 =  atoi(element->Attribute("bottom"));
    int bid = atoi(element->Attribute("id"));

    vector<Element*> words;
    for (TiXmlElement* sub = element->FirstChildElement("word"); sub; sub = sub->NextSiblingElement("word"))
        words.push_back(parseWord(sub));

    return new LineElement(y2,x2,y1,x1,bid,words);
}///End function parse Line

Element * Keywords::parseWord(TiXmlElement* element)
{
    string w =element->Attribute("value");
    double x1 = atoi(element->Attribute("left"));
    double y1 = atoi(element->Attribute("top"));
    double x2 = atoi(element->Attribute("right"));
    double y2 = atoi(element->Attribute("bottom"));
    int bid = atoi(element->Attribute("id"));

    vector<Letter*> chars;

    for (TiXmlElement* sub = element->FirstChildElement("char"); sub; sub = sub->NextSiblingElement("char"))
        chars.push_back(parseChar(sub));

    return new  Element(w,y1, x1, y2,x2,-1,bid,chars);
}///End function parse word

Letter * Keywords::parseChar(TiXmlElement* element)
{
    string w = element->Attribute("value");
    double x1 = atoi(element->Attribute("left"));
    double y1 = atoi(element->Attribute("top"));
    double x2 = atoi(element->Attribute("right"));
    double y2 =  atoi(element->Attribute("bottom"));
    int bid = atoi(element->Attribute("id"));
    return new Letter(w,y1,x1,y2,x2,bid);
}

メモリ リークがあると思います。返された後にポインタを削除するにはどうすればよいですか? デストラクタを使用してメモリを解放するにはどうすればよいですか? 実行時エラー bad:alloc が発生します

4

2 に答える 2

6

@BalogPal が言ったように、これを修正する最も簡単な方法は、C++ を Java のように扱うのをやめることです。これらの関数からポインターを返す理由はありません。次のようなことを試してください:

Block Keywords::parseBlock(TiXmlElement* element)
{
    double x1 = atoi(element->Attribute("left"));
    double y1 = atoi(element->Attribute("top"));
    double x2 = atoi(element->Attribute("right"));
    double y2 = atoi(element->Attribute("bottom"));
    double width = abs(x2 - x1);
    int bid = atoi(element->Attribute("id"));

    vector<LineElement> lines;
    for (TiXmlElement* sub = element->FirstChildElement("line"); sub; sub = sub->NextSiblingElement("line"))
        lines.push_back(parseLine(sub));

    return Block(y2, x2, y1, x1, bid, width, lines);
}

LineElement Keywords::parseLine(TiXmlElement* element)
{
    double x1 = atoi(element->Attribute("left"));
    double y1 = atof(element->Attribute("top"));
    double x2 = atoi(element->Attribute("right"));
    double y2 = atoi(element->Attribute("bottom"));
    int bid = atoi(element->Attribute("id"));

    vector<Element> words;
    for (TiXmlElement* sub = element->FirstChildElement("word"); sub; sub = sub->NextSiblingElement("word"))
        words.push_back(parseWord(sub));

    return LineElement(y2, x2, y1, x1, bid, words);
}

Element Keywords::parseWord(TiXmlElement* element)
{
    string w = element->Attribute("value");
    double x1 = atoi(element->Attribute("left"));
    double y1 = atoi(element->Attribute("top"));
    double x2 = atoi(element->Attribute("right"));
    double y2 = atoi(element->Attribute("bottom"));
    int bid = atoi(element->Attribute("id"));

    vector<Letter> chars;

    for (TiXmlElement* sub = element->FirstChildElement("char"); sub; sub = sub->NextSiblingElement("char"))
        chars.push_back(parseChar(sub));

    return Element(w, y1, x1, y2, x2, -1, bid, chars);
}

Letter Keywords::parseChar(TiXmlElement* element)
{
    string w = element->Attribute("value");
    double x1 = atoi(element->Attribute("left"));
    double y1 = atoi(element->Attribute("top"));
    double x2 = atoi(element->Attribute("right"));
    double y2 = atoi(element->Attribute("bottom"));
    int bid = atoi(element->Attribute("id"));
    return Letter(w, y1, x1, y2, x2, bid);
}

引数をポインターとして残した唯一の理由は、それがあなたTiXmlElementFirstChildElement()NextSiblingElement()関数が返すものだからです。通常、TiXmlElement &element代わりに ( ) を参照するようにします。これは、 を渡すことができないため、より安全ですNULL

パフォーマンス上の理由からコピーを本当に回避する必要があり、コンパイラがそれを自動的に行うほど賢くない場合は、参照カウントされるスマート ポインターを使用できるため、それらについて心配する必要はありませんdelete

std::shared_pointer<Block> Keywords::parseBlock(TiXmlElement* element)
{
    double x1 = atoi(element->Attribute("left"));
    double y1 = atoi(element->Attribute("top"));
    double x2 = atoi(element->Attribute("right"));
    double y2 = atoi(element->Attribute("bottom"));
    double width = abs(x2 - x1);
    int bid = atoi(element->Attribute("id"));

    vector<std::shared_pointer<LineElement> > lines;
    for (TiXmlElement* sub = element->FirstChildElement("line"); sub; sub = sub->NextSiblingElement("line"))
        lines.push_back(parseLine(sub));

    return std::shared_pointer<Block>(new Block(y2, x2, y1, x1, bid, width, lines));
}

// etc.
于 2013-06-19T20:30:46.790 に答える
-1

通常、ポインターを「返す」ことはありません。ポインターをパラメーターとして関数に渡し、関数内でそれに値を割り当てることができます。ポインターはメモリの場所であるため、関数が戻ったときにこの値はポインターに残ります。必要なものにポインタを使用した後、メモリ管理を行うことができます。

于 2013-06-19T20:26:50.180 に答える