创建指向while语句中的指针的指针

Create pointer to pointer in while statement issue

本文关键字:指针 语句 while 创建      更新时间:2023-10-16

在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,我需要有一个指向指针的指针。还是不?

问题是将指向局部变量t的指针放入映射中。在每个循环之后,t被破坏,指针不再有效。

我完全不知道你为什么要使用指针,更不用说指针对指针了。你可能想把元组本身放在地图上:

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

我创建了一个while语句,在该语句中,我将一个指针分配给指向映射的指针

很抱歉这么说,但在我看来,你有比t相同更大的问题(这看起来像xy问题)。

考虑(按顺序)这些替代方案之一:

  • 按值存储元组

  • 通过单个指针存储元组(比"按值"差,比"按指针对指针"好)。如果你能做到这一点,可以考虑在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;
}

(您的方法是将同一个本地(堆栈)变量的地址添加到映射中,这将导致在退出本地函数后出现未定义的行为)。

您为什么对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++;
    }

好吧,t的地址总是相同的,因为它是存储在堆栈上的局部变量。每次你进入区块,t都会被分配在同一地点(就像你从while体内出来后销毁t一样)。

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

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++;
    }

更好的方法是使用智能指针而不是原始指针。

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