对于长度超过10个字母的字符串,char*的更改没有任何明显的原因.为什么?
With a string longer than 10 letters, char* changes without any apparent reason. Why?
在步骤2中,我只更改name_C
的值。为什么name_B
也会改变?
这是代码:
#include <cstdlib>
#include <dirent.h>
#include <iostream>
#include <fstream>
#include <direct.h>
using namespace std;
int main(int argc, char *argv[])
{
// step 1
char *name_A;
char *name_B;
char *name_C;
string str_L = "hello";
string str_M = "stringVar_A"; ;
name_A = (char *) str_M.c_str();
name_B = (char *) (str_L + "-car-" + str_M).c_str();
name_C = (char *) str_L.c_str();
cout << " name_A= " << name_A << endl;
cout << " name_B= " << name_B << endl;
cout << " name_C= " << name_C << endl << endl << endl;
// step 2
string str_N = "myStringMyString"; // (in my real code, i can't put this line in step 1)
string str_R = "ABCDEFGHI" + str_N; // (in my real code, i can't put this line in step 1)
name_C = (char *)str_R.c_str(); // change only name_C
cout << " name_A= " << name_A << endl;
cout << " name_B= " << name_B << endl; // changed, why?
cout << " name_C= " << name_C << endl; // changed, ok.
system("PAUSE");
return EXIT_SUCCESS;
};
这里的输出:
(step 1:)
name_A= stringVar_A
name_B= hello-car-stringVar_A
name_C= hello
(step 2:)
name_A= stringVar_A
name_B= ABCDEFGHImyStringMyString
name_C= ABCDEFGHImyStringMyString
带有:
string str_N = "myString"; // in step 2...
name_B
不变
如果str_N
超过10个字母,为什么name_B
会发生变化
有人能帮我理解这种行为吗?
调用c_str
返回的指针只有在相应的std::string
保持在作用域内且未修改时才有效。
在此之外访问它的行为是不明确的。
例如,(str_L + "-car-" + str_M).c_str();
将返回匿名临时的c_str
。分配后,它将立即无效。在您的情况下,name_B
无效。
另外,不要丢弃c_str()
的const char*
返回。它是const
,原因很充分:您不应该试图通过该指针修改字符串内容。
您正在导致未定义的行为。
name_B = (char *) (str_L + "-car-" + str_M).c_str();
根据std::string::operator+的结果创建一个temoprary字符串,从中提取C字符数组,但没有人真正对临时字符串进行Cathed。
当const引用没有捕获临时对象时,它会立即被销毁。字符串析构函数取消分配内部字符数组并使name_B无效。
因此,这是未定义的行为,因为您试图使用不再有效的内存地址。
std::string::c_str()
返回指向std::string
内部缓冲区的指针,并保证:
- 它指向一个以NUL结尾的字符串
- 范围[
c_str()
;c_str() + size()
]是有效的
在您的情况下,name_B
指向临时对象name_B = (str_L + "-car-" + str_M).c_str();
的内部缓冲区,当您尝试使用它时,该缓冲区将导致"未定义的行为"。
当您对堆栈进行一些修改时(您定义了两个新的std::string
),您可能会更改name_B
所指向的堆栈位置(因为临时内存保留的内存已经释放)。
如果你真的必须从std::string
中获得老式的C字符串,请确保:
- 当CCD_ 24被修改或破坏时,从CCD_
- 因此您不会从临时调用
std::string::c_str()
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 为什么瓦尔格林德在不释放恶意内存后没有报告任何问题?
- 为什么 std::lerp 不适用于任何已实现所需操作的类型?
- 为什么我的 HWID 锁接受任何acceptedSerial_2值
- 为什么静态数组成员变量在调用对象的实例后不显示任何内容?
- 可能我知道为什么这段代码没有给出任何输出吗?
- 为什么下面的Hello World程序在PowerShell上没有显示任何输出?同一程序在CMD上显示正确的输出
- 为什么 c++ 中的 main() 函数不采用除 int 和 void 之外的任何其他返回类型
- 为什么这个程序对投掷不做任何事情?
- 执行此代码时,它不显示任何输出.为什么?
- 给定一个 3 x 3 矩阵或任何 n x n 矩阵,为什么我的以下函数找不到对角线差异?
- 为什么我的突变器函数没有设置任何内容?还是我的构造函数?
- 为什么 std::erase(std::erase_if) 不是适用于<algorithm>任何容器的模板?
- 为什么套接字中的 recv() 函数不返回任何内容?
- 为什么字符串没有更新并且最终没有打印任何内容
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 为什么我的主文件.cpp不打印头文件中的任何内容
- PLT代码中的隔离错误.任何想法为什么
- 按回车键后,程序没有输出任何结果.为什么会这样
- 语句调用构造函数,但对构造函数不做任何操作——为什么它不能编译