在while语句问题中创建指向指针的指针

时间:2013-11-25 13:19:09

标签: c++ pointers

在Visual Studio 2010中我创建了一个while语句,在其中我指定了一个指向地图的指针。 例如:

    std::map<int,std::tuple<int,std::string>** > dmap;
        int i=0;
        while (i<3){

            std::tuple<int,std::string>* t = new std::tuple<int,std::string>(10+i,std::string("test"));
            dmap[i] = &t; 
            dmap[i + 1 ] = &t;
            i++;
        }
.
.
.    
for (auto it = d.begin();it!=d.end();++it)
    {
        if(*(it->second) != nullptr){
            delete *(it->second);
            *(it->second) = nullptr;
        }


    }

问题是&t的地址始终相同,因此在最后,对于我输入的所有密钥,地图始终包含最后*t值。

问题是什么? (解决)

[编辑] 现在我修改代码beacause它不完整之前,如果我想避免删除nullptr我需要有一个指针指针。或者不是?

4 个答案:

答案 0 :(得分:3)

问题在于您将指向局部变量t的指针放入地图中。在每个循环之后,t被销毁并且指针不再有效。

我根本不知道你为什么要使用指针,更不用说指针了。您可能希望将元组本身放在地图中:

std::map<int,std::tuple<int,std::string>> dmap;
for (int i = 0; i<3; ++i){
    dmap[i] = {10+i, "test"};
}

答案 1 :(得分:1)

  

我创建一个while语句,在其中我指定一个指向地图指针的指针

很抱歉这样说,但听起来我觉得你遇到的问题比t都相同(这看起来像xy problem)。

考虑(按顺序)其中一种选择:

  • 按值存储您的元组

  • 通过单个指针存储元组(比“按值”更差,优于“通过指针指向”)。如果您可以这样做,请考虑将地图声明为std::shared_ptr<std::tuple<...>>

  • 如果你真的需要一个指向元组指针的指针映射,可以考虑创建一个最小的代理对象,它就像一个指向内部的指针的智能指针(并以安全的方式为你管理分配),并像常规一样从外面输入(并相应地重新声明你的地图)。

无论哪种方式,如果你真的需要一个指向元组指针的指针映射(由于某种原因),分配应该像这样完成:

std::map<int,std::tuple<int,std::string>**> dmap;
int i=0;
while (i<3) {
    *dmap[ i ] = new std::tuple<int,std::string>{10 + i, "test"};
    ++i;
}

(你这样做的方法是将相同的本地(堆栈)变量的地址添加到地图中,这会在退出本地函数后导致未定义的行为。)

答案 2 :(得分:0)

嗯,t的地址始终相同,因为它是存储在堆栈中的局部变量。每次进入该区块时,t都会在同一位置分配(因为您在离开t机构后正在销毁while

相反,您需要在堆上分配它(如果这真的是您想要做的)。

std::tuple<int,std::string>** t = new  std::tuple<int,std::string>*();
*t = new std::tuple<int,std::string>(10+i,std::string("test"));
dmap[i] = t;

我无法看到你想要完成的任务,但这将是一个更好的解决方案:

std::map<int,std::tuple<int,std::string>* > dmap;
    int i=0;
    while (i<3){

        std::tuple<int,std::string>* t = new std::tuple<int,std::string>(10+i,std::string("test"));
        dmap[i] = t;
        i++;
    }

更好的方法是使用智能指针代替原始指针。

更好的方法是按值存储对象(根本没有指针)。

答案 3 :(得分:0)

您为什么对std::tuple<int,std::string>**感兴趣?

std::tuple<int,std::string>*不足够吗?

std::map<int,std::tuple<int,std::string>* > dmap;
    int i=0;
    while (i<3){

        std::tuple<int,std::string>* t = new std::tuple<int,std::string>(10+i,std::string("test"));
        dmap[i] = t;
        i++;
    }