简体   繁体   English

矢量 push_back 添加新项目

[英]vector push_back add new items

I need add items to a vector who are created as std::vector<char*> Lista;我需要将项目添加到创建为std::vector<char*> Lista;的向量中。

then i do:然后我做:

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

        Lista.push_back(txt);
    }

but if i loop Lista items it show show:但是如果我循环显示它显示的 Lista 项目:

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

Items > [0] num5项目 > [0] num5

Items > [1] num5项目 > [1] num5

Items > [2] num5项目 > [2] num5

Items > [3] num5项目 > [3] num5

Items > [4] num5项目 > [4] num5

Items > [5] num5项目 > [5] num5

what i'm doing wrong?我做错了什么? i need use char* not string.我需要使用 char* 而不是字符串。

You're pushing five pointers to the same array into your vector, so when you print the contents of the array pointed to by each pointer they're all the same.您将五个指向同一个数组的指针推入向量中,因此当您打印每个指针指向的数组内容时,它们都是相同的。

You only have a single array: txt .您只有一个数组: txt Each time through your loop, you write new contents into that array and push a pointer to it into Lista .每次通过循环时,您都会将新内容写入该数组并将指向它的指针推入Lista So the first time through your loop you have this:所以第一次通过你的循环你有这个:

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

Then the second time through you modify txt and add another pointer to it to Lista , so you have this:然后第二次通过你修改txt并将另一个指向它的指针添加到Lista ,所以你有这个:

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

And so on.等等。 Every element of Lista contains a pointer to the same array, which you modify in each iteration of your loop. Lista的每个元素都包含一个指向同一数组的指针,您可以在循环的每次迭代中修改该数组。 When you go back and print the contents of the array pointed to by each element of Lista , they all point to the same array, so the same thing gets printed for each.当您返回并打印Lista的每个元素指向的数组内容时,它们都指向同一个数组,因此每个元素都会打印相同的内容。

If you want to store different text in each element of Lista , you will need to create a separate string for each.如果要在Lista的每个元素中存储不同的文本,则需要为每个元素创建一个单独的字符串。 The easiest way to do that would be to change the type of Lista to std::vector<std::string> and let the std::string class handle allocating space for each string:最简单的方法是将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);
}

Then you can use std::string 's data member function to get a pointer to the string's underlying char* if you need to pass it to some interface that doesn't support std::string .然后,您可以使用std::stringdata成员函数来获取指向字符串底层char*的指针,如果您需要将它传递给某些不支持std::string的接口。 Keep in mind that the lifetime of the arrays pointed to by those pointers are tied to the lifetime of the std::string object, so be careful not to use them after the std::string (or the std::vector that contains it) goes out of scope.请记住,这些指针指向的数组的生命周期与std::string对象的生命周期相关,因此请注意不要在std::string (或包含它的std::vector之后)使用它们) 超出范围。

If you absolutely do not want to use std::string to manage the lifetime of your arrays, you can allocate them yourself with new[] , just remember that you must then remember to delete[] them when you're done with them to avoid leaking memory:如果您绝对不想使用std::string来管理数组的生命周期,您可以使用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;
}

There are very few legitimate reasons to do this though.不过,这样做的正当理由很少。 In 99.9% of cases you should use std::string or some sort of smart pointer to manage your memory.在 99.9% 的情况下,您应该使用std::string或某种智能指针来管理您的内存。


Note: Your program also exhibits undefined behavior because you access your array out of bounds with Lista[x+1] = txt ;注意:您的程序还表现出未定义的行为,因为您使用Lista[x+1] = txt访问数组越界; you should get rid of that line.你应该摆脱那条线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM