为什么从 int 到 const char* 的转换会破坏 C++
why does concersion from int to const char* break C++
你好,最近我在 Visual studio 学习 C++,当我想用我的方法记录一个 int 时遇到了一个问题,我需要将它转换为 const char* 但是当我这样做时,事情只是崩溃是我的代码:
#include <iostream>
#include <math.h>
#include <Windows.h>
using namespace std;
double pi = 3.14159265358979323846;
class Log {
int level = 1;
public:
void set_Level(const char* lvl)
{
if (lvl == "LOW")
{
level = 1;
}
else if (lvl == "NORMAL")
{
level = 2;
}
else if (lvl == "HIGH")
{
level = 3;
}
else
{
level = 1;
}
}
void Error(const char* message)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x04);
cout << "[ERROR]: " << message << endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
void Warning(const char* message)
{
if (level != 3)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x06);
cout << "[WARNING]: " << message << endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
}
void Info (const char* message)
{
if (level == 1)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x03);
cout << "[INFO]: " << message << endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
}
};
int main()
{
Log log;
log.set_Level("LOW");
int x = 10;
log.Info( (const char*) x);
}
它出错并弹出一个页面说:
这不是我的 class 因为如果我 运行 log.Info("hi");
它工作得很好!
将 int
转换为 const char *
是不安全的。
我会这样做
std::string s = std::to_string(x);
log.info(s.c_str());
或
std::ostringstream oss;
oss << x;
log.Info(oss.str().c_str());
"hi"
是一个空终止字符串文字。 int x
不是。
当您(错误地)将 int x
转换为 const char *
时,您是在告诉编译器,这是一个指向连续字节集的指针,该字节集的末尾有一个空终止字符顺序。当然,int
不是一个指针——因此它的值 10
可能是一个无效的起始地址(而且仅此一项很可能会导致段错误)。即使它是有效的,它也会“指向”某个“任意”地址。 C++ 允许您在按原样投射时进行此转换 - 但您不应该这样投射。
使用static_cast<const char *>(x)
然后你应该得到一个编译器警告警告:)
这是您从编译器得到的错误:
<source>: In function 'int main()':
<source>:13:10: error: invalid 'static_cast' from type 'int' to type 'const char*'
13 | xxxx(static_cast<const char *>(x));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
ASM generation compiler returned: 1
char*
是指针类型,存储地址作为它的值。当您将 10
转换为 const char*
时。这表示地址值 10
,可能无法访问并导致崩溃和分段错误。
您需要做的是使用 itoa
函数将 10
转换为 C 风格的字符串。
你好,最近我在 Visual studio 学习 C++,当我想用我的方法记录一个 int 时遇到了一个问题,我需要将它转换为 const char* 但是当我这样做时,事情只是崩溃是我的代码:
#include <iostream>
#include <math.h>
#include <Windows.h>
using namespace std;
double pi = 3.14159265358979323846;
class Log {
int level = 1;
public:
void set_Level(const char* lvl)
{
if (lvl == "LOW")
{
level = 1;
}
else if (lvl == "NORMAL")
{
level = 2;
}
else if (lvl == "HIGH")
{
level = 3;
}
else
{
level = 1;
}
}
void Error(const char* message)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x04);
cout << "[ERROR]: " << message << endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
void Warning(const char* message)
{
if (level != 3)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x06);
cout << "[WARNING]: " << message << endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
}
void Info (const char* message)
{
if (level == 1)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x03);
cout << "[INFO]: " << message << endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
}
};
int main()
{
Log log;
log.set_Level("LOW");
int x = 10;
log.Info( (const char*) x);
}
它出错并弹出一个页面说:
这不是我的 class 因为如果我 运行 log.Info("hi");
它工作得很好!
将 int
转换为 const char *
是不安全的。
我会这样做
std::string s = std::to_string(x);
log.info(s.c_str());
或
std::ostringstream oss;
oss << x;
log.Info(oss.str().c_str());
"hi"
是一个空终止字符串文字。 int x
不是。
当您(错误地)将 int x
转换为 const char *
时,您是在告诉编译器,这是一个指向连续字节集的指针,该字节集的末尾有一个空终止字符顺序。当然,int
不是一个指针——因此它的值 10
可能是一个无效的起始地址(而且仅此一项很可能会导致段错误)。即使它是有效的,它也会“指向”某个“任意”地址。 C++ 允许您在按原样投射时进行此转换 - 但您不应该这样投射。
使用static_cast<const char *>(x)
然后你应该得到一个编译器警告警告:)
这是您从编译器得到的错误:
<source>: In function 'int main()':
<source>:13:10: error: invalid 'static_cast' from type 'int' to type 'const char*'
13 | xxxx(static_cast<const char *>(x));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
ASM generation compiler returned: 1
char*
是指针类型,存储地址作为它的值。当您将 10
转换为 const char*
时。这表示地址值 10
,可能无法访问并导致崩溃和分段错误。
您需要做的是使用 itoa
函数将 10
转换为 C 风格的字符串。