为什么以下程序 - 将 c 字符串传递给函数 - 没有产生所需的输出?

Why does the following program - passing c string to function - not produce the desired output?

我有一个简单的问题C++(或C)。 为什么以下程序将 c 字符串传递给函数,却没有产生所需的输出?

#include <cstdio>
#include <cstring>

void fillMeUpSomeMore( char** strOut )
{
    strcpy( *strOut, "Hello Tommy" );
}


int main()
{
    char str[30];
    //char* strNew = new char[30];
    fillMeUpSomeMore( (char**) &str ); // I believe this is undefined behavior but why?
    //fillMeUpSomeMore( (char**) &strNew ); // this does work
    std::printf( "%s\n", str );
    //std::printf( "%s\n", strNew ); // prints "Hello Tommy"
    //delete[] strNew;
}

我所做的只是将 char 数组 str 的地址传递给一个函数,该函数采用指向 char 的指针(在显式转换之后应该没问题)。 但是程序什么都不打印。 然而,这将适用于已动态分配的 strNew 变量。

我知道我不应该这样做,而是应该使用 std::string。我这样做只是为了学习目的。谢谢

我正在使用 g++ 和 C++17 (-std=c++17) 进行编译。

char **是指向字符的指针。这意味着,如果它不是空指针,它应该是内存中有指针的某个地方的地址。

char str[30]定义了一个30char的数组。 &str 是那个数组的地址。那里没有指针,只有 30 char。因此,&str 不是 char **.

所以 (char**) &str 不好。它告诉编译器将数组的地址视为指针的地址。那是行不通的。

如果您改用 char *strNew = new char[30];,则表示 strNew 是一个指针,它是用 30 char 数组的第一个 char 的地址初始化的.那么,由于strNew是一个指针,&strNew是一个char *的地址,所以是一个char **(char **) &strNew也没有错。

通常,您应该避免转换并注意编译器警告。当编译器告诉您类型有问题时,努力理解问题并通过更改涉及的类型或表达式来修复它,而不是使用强制转换。

Why does the following program, passing c string to function, not produce the desired output?

当你做像 (char **) 这样的转换时,你并没有指定你想要 const_caststatic_cast 和/或 reinterpret_cast 中的哪一个,而是指定哪个是从表达式的类型到目标类型所必需的。

表达式 &str 的类型为 char (*)[30],因此您正在对不相关的类型执行 reinterpret_cast

表达式 &strNew 的类型为 char **,因此您根本不需要强制转换。

当您编写 C++ 时,您应该永远不要使用 C 风格转换。您应该改用您想要的任何 C++ 转换(static_castconst_castreinterpret_cast)。