gpt4 book ai didi

c++ - 当访问要插入 union vector 的字符串的字符时, vector 中的字符串会变得困惑

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:47:14 25 4
gpt4 key购买 nike

这是一个 SSCCE (显示问题的简单示例):

#include <iostream>
#include <string>
#include <vector>
using namespace std;

enum Type {oInt, oFloat, oString, oArray};

struct Object; // fwd decl for union
union ObjectNative {
int oInt;
float oFloat;
const char* oString;
vector<Object>* oArray;
};
struct Object {
Type type;
ObjectNative obj;
};

vector<Object> exec(vector<string> tokens, vector<Object> stack);
void printStack(vector<Object> stack);

int main() {
vector<string> tokens{"test", "another test", "even more test", "test test", "test test test", "lotsa test"};
vector<Object> stack;
stack = exec(tokens, stack);
printStack(stack);

return 0;
}

vector<Object> exec(vector<string> tokens, vector<Object> stack) {
for (string s : tokens) {
ObjectNative nObj;

// !!!!!!!!!!!!!!!!!!!!!! THIS LINE !!!!!!!!!!!!!!!!!!!!!!
s[0];

nObj.oString = s.c_str();
Object obj = Object{oString, nObj};
stack.push_back(obj);

// debugging lines
printStack(stack);
cout << "-------" << endl;
}
return stack;
}

void printStack(vector<Object> stack) {
for (unsigned int i = 0; i < stack.size(); i ++) {
Object o = stack[i];
cout << o.obj.oString;
cout << endl;
}
}

注意我在 exec 函数中标记的行:

s[0];

我只是访问字符串中的第一个字符;我什至没有用它做任何事情!但是,如果我注释掉该行,我会得到正确的输出:

test
-------
test
another test
-------
(etc....)
-------
test
another test
even more test
test test
test test test
lotsa test

但是对于那句话,我...呃,我不确定发生了什么。这是输出:

test
-------
ä7R
another test
-------
ä7R
even more test
even more test
-------
test test
ä7R
ä7R
test test
-------
test test
test test test
test test test
test test
test test test
-------
lotsa test
ä7R
ä7R
lotsa test
ä7R
lotsa test
-------
lotsa test
ä7R
ä7R
lotsa test
ä7R
lotsa test

看起来代码没有问题,但显然我做错了什么。为什么 vector 会像这样损坏,到底是什么原因造成的,不对字符串的第一个字符做任何处理?

最佳答案

const char * 的生命周期由 string::c_str() 返回是有限的。如果您试图保留这些字符串,则需要将它们复制到专用存储中。

字符串 s被来自 tokens 的新字符串替换在每次迭代中。当 for循环将新字符串分配给 s在下一次迭代中,允许使 c_str() 无效结果来自上一次迭代。

它能正常工作的事实可能是实现的幸运侥幸:在引擎盖下,s可能从 tokens 中的条目中借用了字符串的存储空间.调用operator[] ,但是,可能导致它制作自己的字符串的私有(private)拷贝。这可以解释 c_str() 的行为差异。 .

要将拷贝保存在专用存储中,需要为其分配空间并将字符串复制到其中。像下面这样的代码就足够了:

nObj.oString = new char[s.size() + 1];  // allocate the space
std::strcpy( nObj.oString, s.c_str() ); // copy in the string

现在,从技术上讲,这不会复制整个 string如果它包含 ASCII NUL。您的原始代码不关心这些,我上面的建议不会改变这一点。 :-) 你可以找到std::strcpy()<cstring> .

请注意,因为您已经使用 new[] 分配了自己的存储空间, 你必须记住 delete[]稍后当你完成它时,否则你会发生内存泄漏。并确保使用 delete[] , 不是 deletefree() .

关于c++ - 当访问要插入 union vector 的字符串的字符时, vector 中的字符串会变得困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20534016/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com