我们可以用std :: string交换char *吗?

时间:2014-04-11 11:00:08

标签: c++ c++11

Is it legal to modify the result of std::string::op[]?

我想交换char *和std :: string的内容而不能这样做。经过上述链接后,我仍然无法得到我的问题的答案。

这是我正在尝试做的事情,并且无法成功地使用char *交换字符串。代码在VS2010上验证。

更新1 所有的努力都是为了看看我是否能获得任何表现并且没有获得任何SO点数。 :-)
更新2 我在评论中提到了为什么我打算这样做。人们是否还认为这需要暂停?

void Swap(char* const& left, char* const& right)
{
    std::swap(const_cast<char*>(left), const_cast<char*>(right));
}



std::string ToString()
{
   std::string ret(1, ' ');
   char* str = new char[6]();
   strcpy(str, "Jagan");
   Swap(&ret[0], str);

    return ret;
}

4 个答案:

答案 0 :(得分:2)

是的,正如您在链接的帖子中看到的那样,您可以修改string[x]的值,前提是x >= 0 && x < string.size() 标准非常清楚您可以't 修改其他任何东西(你当然不能将&string[x]作为有效的指向可修改的空终止字符串传递 - 记住string.c_str()和{{1 }}返回string.data()

但是,您可以实施:

const char*

live here

答案 1 :(得分:1)

所有代码&ret[0]都会创建一个临时变量,它是指向ret中字符的指针。对swap的调用将此临时变量设置为指针str,并将str设置为此临时变量。结果是ret不受影响,并且您在str中泄漏了内存。为了更清楚,此代码等同于

char* str = new char[6]();
strcpy(str, "Jagan");
char* tmpPtr = &ret[0]
Swap(tmpPtr, str);

所以你可以看到tmpPtr的末尾等于str的原始值。您根本无法访问char*中的内部str指针。这是故意,因为更广泛的问题是你为什么要这样做?即使你可以分配给str的内部指针,这样做将违反封装 - 例如,您假设内部指针是使用new分配的。但是stl容器可以 - 并且确实 - 使用它们自己的内部分配机制,并且应该可以在将来更改它们的实现而不会破坏客户端代码。正如您可以在没有客户的情况下更改班级的实施情况一样。代码破坏。

答案 2 :(得分:1)

无法完成。

std::string没有提供替换其内部数据指针的标准方法。

实际上,并非std::string的所有实现都始终具有指向使用new[]分配的以零终止的字符块的指针。你不应该知道,如果你发现了(信息隐藏/实现隐藏),你当然不应该依赖它。

不同的std::string实现可能会执行以下任何操作:

  • 将大小与非零终止的char *分开。除经典C字符串外,std::string的实例允许包含空字符。
  • 以上内容,但在不同的std::strings之间共享参考计数。你不想干涉这里。
  • 有一个堆栈分配char [16],用于短字符串而不是堆指针

这就是为什么当您想要与自己管理的std::string交换时,您仍然无法复制char*内容

答案 3 :(得分:0)

你所做的事情在很多层面都是错误的。

要将std::stringchar *指向的手动管理字符串“交换”,您需要手动管理该字符串,如:

std::string one = ...;
char *two = ...;

// swap:
std::string tmp = two;
delete[] two;
two = new char[one.size() + 1];
memcpy(two, one.c_str(), one.size() + 1);
one = tmp;