C ++将具有以字符串形式保存的地址的向量转换为新的向量

时间:2018-09-20 01:07:27

标签: c++ pointers vector struct stringstream

我可以得到一些建议吗? 我不是从函数作为指针或引用返回矢量,而是将其作为包含地址的字符串返回。 (我对此有充分的理由。)

^那部分是成功的,我似乎不知道的部分是如何获取返回的字符串(该字符串包含一个向量的地址)并使用它创建一个新的向量。

这是从函数传递到包含其内存地址的字符串中的向量(结构类型):

vector<intructor> intruct;

将向量的地址转换为字符串:成功

string address;
stringstream ss;
ss << &depart;
ss >> address;
return address;

我尝试将其转换回新的向量:失败

    vector<intructor> getIntructorVector(string filePath)
{
stringstream ss;
string address = VectorCreator(filePath);
vector<intructor> intruct;

ss << address;
ss >> &intruct;

return intruct;
}

如果您需要知道,向量就是什么?

struct intructor {
string name;
string dept;
int id;
};

3 个答案:

答案 0 :(得分:1)

我会给传统的StackOverflow警告:“您可能实际上并不想这样做” –在现代C ++中通常不建议手动操作指针,并且在这之间可能会发生很多不好的事情分配对象并传递包含其地址的字符串。话虽如此,这是您的问题:

&intruct是intruct的地址,是一个右值-您无法写入。您当前的代码实际上是在执行以下操作:

{
stringstream ss;
string address = VectorCreator(filePath);
vector<intructor> intruct;
vector<intructor>* intructPtr = &intruct;

ss << address;
ss >> intructPtr; // intruct has not been changed

return intruct;
}

由于您的函数正在返回向量(而不是向量的引用或指针),因此您似乎想要创建所指向向量的副本。在这种情况下,您需要将其分为两个步骤:

{
stringstream ss;
string address = VectorCreator(filePath);
vector<intructor>* intructPtr;

ss << address;
ss >> intructPtr; // intructPtr now points to the resource from VectorCreator

return *intructPtr; // returns a copy of the resource from VectorCreator
}

如果您不想进行复制,那么您的函数应该返回引用vector<intructor>&或指针vector<intructor>* -尽管您所做的一切都非常危险,并且很容易导致错误引用或指向无效位置,从而对程序进行段错误处理。

如果您无法使VectorCreator返回智能指针或向量本身,请务必小心,确保向量不会被删除或增长(可能导致重新分配) 复制。

答案 1 :(得分:0)

尝试这样的方法:

std::vector<intructor> getIntructorVector(std::string filePath)
{
    std::string address = VectorCreator(filePath);
    std::istringstream iss(address);

    void *intruct;
    ss >> intruct;

    return *static_cast<std::vector<intructor>*>(intruct);
}

假设:

  1. 您没有跨越流程边界传递std::string。一个进程所欠的内存地址在另一个进程中无效。

  2. 当调用std::vector时,原始getIntructorVector()仍在内存中,否则您将有一个悬空的指针,因此取消引用将是未定义的行为。

如果这些假设中的任何一个都不成立,那么您尝试执行的操作将无法通过这种方式完成。您必须将整个vector数据序列化string,然后将字符串反序列化 vector,例如:

std::ostream& quoted(std::ostream &out, const std::string &s)
{
    out << '"';
    for(size_t x = 0; x < s.size(); ++x)
    {
        char c = s[x];
        if ((c == '"') || (c == '\\'))
            out << '\\';            
        out << c;
    }
    out << '"';
    return out;
}

...

size_t size = intruct.size();

std::ostringstream oss;
oss << size;

for(size_t x = 0; x < size; ++x)
{
    intructor &i = intruct[x];
    out << ' '; quoted(out, i.name);
    out << ' '; quoted(out, i.dept);
    out << ' ' << i.id;
}

return oss.str();

std::istream& unquoted(std::istream &in, std::string &s)
{
    if (in >> std::ws)
    {
        if (in.peek() == '"')
        {
            in.ignore();

            s.clear();

            char c;
            while (in.get(c))
            {
                if (c == '\\')
                {
                    if (!in.get(c))
                        break;
                }
                else if (c == '"')
                    break;
                s += c;
            }
        }
        else
            in >> s;
    }

    return in;
}

vector<intructor> getIntructorVector(string filePath)
{
    string data = VectorCreator(filePath);
    istringstream iss(data);
    string s;

    size_t size = 0;
    iss >> size;

    vector<intructor> intruct;
    intruct.reserve(size);

    for(size_t x = 0; x < size; ++x)
    {
        intructor i;

        unquoted(iss, i.name);
        unquoted(iss, i.dept);
        iss >> i.id;
        if (!iss) break;

        intruct.push_back(i);
    }

    return intruct;
}

答案 2 :(得分:0)

这一切似乎有点不合常规。它可以工作,但前提是您必须确定原始向量将在整个过程中保持有效。毕竟,字符串内的地址仅 指向 指向原始向量。

struct intructor {
    std::string name;
    std::string dept;
    int id;
};

std::string vec_to_address(std::vector<intructor> const& v)
{
    std::ostringstream oss;
    oss << &v;
    return oss.str();
}

std::vector<intructor>* address_to_vec_ptr(std::string const& s)
{
    void* vp;
    std::istringstream(s) >> vp;
    return reinterpret_cast<std::vector<intructor>*>(vp);
}

int main()
{
    std::vector<intructor> v;
    v.push_back({"Name A", "Dept A", 1});
    v.push_back({"Name B", "Dept B", 2});
    v.push_back({"Name C", "Dept C", 3});

    auto address = vec_to_address(v);

    auto pointer = address_to_vec_ptr(address);

    for(auto const& i: *pointer)
        std::cout << i.name << '\n';

    // if you want a copy of the original vector you can do that
    // like this:
    auto copy_of_original = *pointer;
}

输出:

Name A
Name B
Name C