三行代码  ›  专栏  ›  技术社区  ›  Douglas Ruiz

vector push\u back添加新项目

c++
  •  -3
  • Douglas Ruiz  · 技术社区  · 1 月前

    我需要将创建为的项目添加到向量中 std::vector<char*> Lista;

    然后我会:

    char txt[10];
        for (int x = 0; x <= 5; x++)
        {
            
            sprintf(txt, "num%d", x);
            printf("Add %s\n", txt);
    
            Lista.push_back(txt);
        }
    

    但如果我循环Lista项,它会显示:

    for (int x = 0; x <= Lista.size() - 1; x++)
        {
            printf("Items > [%d] %s\n", x, Lista[x]);
        }
    

    项目(>);[0]num5

    项目(>);[1] num5

    项目(>);[2] num5

    项目(>);[3] num5

    项目(>);[4] num5

    项目(>);[5] num5

    我做错了什么?我需要使用char*而不是string。

    1 回复  |  直到 1 月前
        1
  •  4
  •   Miles Budnek    1 月前

    将指向同一数组的五个指针推入向量中,因此当打印每个指针指向的数组内容时,它们都是相同的。

    您只有一个阵列: txt . 每次通过循环时,都会将新内容写入该数组,并将指向该数组的指针推入 Lista . 因此,第一次通过循环时,您会看到:

    txt
    ┌─────┬─────┬─────┬─────┬──────┬─────┬─────┬─────┬─────┬─────┐
    │     │     │     │     │      │     │     │     │     │     │
    │ 'n' │ 'u' │ 'm' │ '0' │ '\0' │  ?  │  ?  │  ?  │  ?  │  ?  │
    │     │     │     │     │      │     │     │     │     │     │
    └─────┴─────┴─────┴─────┴──────┴─────┴─────┴─────┴─────┴─────┘
    ▲
    │
    └───┐
        │
    ┌───┼───┐
    │   │   │
    │   │   │
    │       │
    └───────┘
    Lista
    

    然后第二次通过你修改 txt文件 并将另一个指向它的指针添加到 利斯塔 ,所以您有:

    txt
    ┌─────┬─────┬─────┬─────┬──────┬─────┬─────┬─────┬─────┬─────┐
    │     │     │     │     │      │     │     │     │     │     │
    │ 'n' │ 'u' │ 'm' │ '1' │ '\0' │  ?  │  ?  │  ?  │  ?  │  ?  │
    │     │     │     │     │      │     │     │     │     │     │
    └─────┴─────┴─────┴─────┴──────┴─────┴─────┴─────┴─────┴─────┘
    ▲ ▲
    │ └─────────┐
    └───┐       │
        │       │
    ┌───┼───┬───┼───┐
    │   │   │   │   │
    │   │   │   │   │
    │       │       │
    └───────┴───────┘
    Lista
    

    等等每个元素 利斯塔 包含指向同一数组的指针,您可以在循环的每次迭代中修改该数组。返回并打印 利斯塔 ,它们都指向相同的数组,因此每个数组都会打印相同的内容。

    如果要在的每个元素中存储不同的文本 利斯塔 ,则需要为每个创建单独的字符串。最简单的方法是更改 利斯塔 std::vector<std::string> std::string 类句柄为每个字符串分配空间:

    for (int x = 0; x <= 5; ++x) {
        std::string text = std::format(num{}, x);  // Use std::ostringstream or sprintf if your compiler doesn't support std::format
        Lista.push_back(text);
    }
    

    然后您可以使用 标准::字符串 data 成员函数,以获取指向字符串的基础 char* 如果需要将其传递给不支持 标准::字符串 . 请记住,这些指针指向的数组的生存期与 标准::字符串 对象,因此请小心不要在 标准::字符串 (或 std::vector 包含它)超出范围。

    如果你绝对不想使用 标准::字符串 要管理阵列的生存期,您可以使用 new[] ,请记住,您必须记住 delete[] 当您处理完它们以避免内存泄漏时:

    for (int x = 0; x <= 5; ++x) {
        char* txt = new char[5];
        sprintf(txt, "num%d", x);
        Lista.push_back(txt);
    }
    
    // ... stuff
    
    for (char* txt : Lista) {
        delete[] txt;
    }
    

    但这样做的正当理由很少。在99.9%的情况下,您应该使用 标准::字符串 或者某种智能指针来管理你的内存。


    注意:您的程序还表现出未定义的行为,因为您使用 Lista[x+1] = txt ; 你应该去掉那条线。