如何将一个char *分配给另一个char *

时间:2016-04-02 08:58:26

标签: c++

这是我的第一个问题。

我有一段代码:

char* str1 = "yes" ;
char* str2 = "no" ;
*str1 = *str2;    //----crash

*str1 = *str2; //here program crashes.

当我可以使用整数指针执行相同操作时,为什么不使用char指针。 请解释一下。

3 个答案:

答案 0 :(得分:4)

此原始代码,

char* str1 = "yes" ;
char* str2 = "no" ;
*str1 = *str2;    //----crash

*str1 = *str2; //here program crashes.

... 无效,不允许,从C ++ 11及更高版本开始。我们现在在C ++ 14,很快就会在C ++ 17上。

C ++ 11编译器对此有何评论?例如,具有选项-std=c++14的MinGW g ++ 5.1.0,对它说什么?

C:\my\forums\so\121> g++ foo.cpp
foo.cpp: In function 'int main()':
foo.cpp:3:18: error: ISO C++ forbids converting a string constant to 'char*' [-Wpedantic]
     char* str1 = "yes" ;
                  ^
foo.cpp:4:18: error: ISO C++ forbids converting a string constant to 'char*' [-Wpedantic]
     char* str2 = "no" ;
                  ^

C:\my\forums\so\121> _

但是,Visual C ++ 2015 update 2错误地接受了代码。

从语言中删除隐式转换为char*的原因恰恰是它不安全。它允许代码尝试修改文字,就像这段代码一样。但是文字可以存储在只读存储器中,然后可能导致崩溃(就像它对OP所做的那样)或其他不良行为。它只是未定义的行为,任何事情都可能发生,包括代码似乎“正常工作”。

如何解决?

使用 std::string

像这样:

#include <string>
using namespace std;

auto main() -> int
{
    string str1 = "yes" ;
    string str2 = "no" ;
    str1 = str2;    // OK.
}

如果你绝对想要使用通过指针处理的C级零终止字符串,也许是为了与某些C代码兼容,那么根据指针使用const,使用本地或动态分配的数组进行存储在适当的情况下,使用C标准库的字符串函数,或使用自己的函数,它们是非常简单的函数:

#include <assert.h>
#include <string.h>     // The ".h" header is a C++ version of C's header.

auto main() -> int
{
    char str1[] = "yes" ;
    char const* const str2 = "no" ;

    int const n2 = strlen( str2 );
    assert( sizeof( str1 ) > n2 );
    strcpy( str1, str2 );
    assert( strcmp( str1, "no" ) == 0 );
}

答案 1 :(得分:1)

请注意,char*是指向char的指针,而不是字符串对象。文字"yes"实际上是const char*,因为文字将是程序数据部分中的常量数据。为了与C C ++兼容,仍允许使用char初始化const char* *。

另请注意,指针上的一元*运算符会取消引用指针。

现在,您在此处将str2'n')的第一个字符分配给str1的第一个字符。由于str1的第一个字符在程序数据部分中是常量,因此当然会失败。

如果你真的想要分配第一个char,首先在堆上产生一个char数组:

char* str1 = (char*)malloc(4); // here str1 is non const
strncpy(str1, "yes", 4);

const char* str2 = "no";

*str1 = *str2; // now str1 contains "nes".

我假设您正在尝试使用字符串。请更喜欢std::string

std::string str1 = std::string("yes");
std::string str2 = std::string("no");

str1 = str2 // now str1 is "no" as well.

使用C ++ 14字符串文字,你可以使它更优雅:

auto str1 = "yes"s;
auto str2 = "no"s;

str1 = str2 // now str1 is "no" as well.

只要合理,使用标准库而不是C遗留构造。你可能不会更好。

答案 2 :(得分:0)

根据评论,OP只想将str1设为"no"

而不是

*str1 = *str2;

你应该做

str1 = str2;

str1是一个指向给定字符串的第一个字符的指针。 *str取消引用指针,为您提供字符串str1的第一个字符。因此,您的代码正在尝试将str1的第一个字符设置为str2的第一个字符

在我的代码中,我将str1指向同一位置ass str2,这实际上会为您提供指向同一内存位置的两个变量。

如果要将str2的内容复制到str1,请使用strcpy函数。