为什么传递char []不起作用,但(不推荐的转换)char *呢?

时间:2013-09-04 14:41:40

标签: c++

我无法解释自己出现以下行为的原因。我初始化两个文本,一个作为char *,另一个作为char []并将它们放入一个结构中。两者在结构中看起来很好,但是在main中,第二个丢失了,第一个给了我一个我理解的编译器警告(不推荐将字符串常量转换为char *)。

这是我在这里提出的第一个问题,我为任何错误的事情道歉。是的,我尝试搜索,但与char *和char []相关,出现了很多Q& A,没有一个我发现类似于我遇到的嵌套问题。

从附加的代码我得到输出:

get_struct: 5 test test2
main: 5 test

(最后的测试2失踪)

所以代码:

    #include <iostream> 

    typedef struct {
        double a_double;
        char* a_char1;
        char* a_char2;
    } testStruct;

    testStruct make_struct(double d, char* c1, char* c2) {          
        testStruct t;

        t.a_double = d;
        t.a_char1 = c1;
        t.a_char2 = c2;

        return t;
    }

    void get_struct(testStruct &t) {    
        char* test_char1 = "test";
        char test_char2[] = "test2";
        double test_double = 5;

        t = make_struct(test_double, test_char1, test_char2);

        std::cout << "get_struct: " << t.a_double << " " 
            << t.a_char1 << " " << t.a_char2  << std::endl;
    }

    int main() {
        testStruct t;
        get_struct(t);
        std::cout << "main: " << t.a_double << " " 
            << t.a_char1 << " " << t.a_char2 << std::endl;
        return 0;
    }

3 个答案:

答案 0 :(得分:3)

您遇到的问题是存储指向结构中局部变量的指针。

对于test_char2数组,一旦get_struct函数返回,它就不再存在。这意味着指针a_char2不再指向有效字符串,并且取消引用此指针是未定义的行为。

第一个指针工作的原因是因为它没有指向局部变量,它指向一个字符串文字,而那些存储在内存的其他位置。

在C ++中编码时,不再有理由使用指针或数组作为字符串,而是使用std::string类。

答案 1 :(得分:2)

char* test_char1 = "test";

这将创建一个指向字符串文字的指针。字符串文字是const但是,由于历史原因,该语言允许指针为非const;但是,这已被弃用,因此警告。如果您尝试修改字符串,那么您将获得未定义的行为。

char test_char2[] = "test2";

这将创建一个本地数组,通过复制字符串文字进行初始化。它不是const,因此您可以根据需要进行修改。但是一旦函数返回,它就会被破坏,因此你的结构会以悬空指针结束无效内存。这就是当您尝试在main中打印时未定义的行为。

两条建议:

  • 不要使用C风格的字符数组和指针来表示字符串;使用std::string。它可以为您管理内存,避免您在这里遇到的终身问题。
  • 如果你真的想搞乱数组和指针,请使用const char*,除非你真的需要修改它。否则,很难使用字符串文字。

答案 2 :(得分:1)

将字符串文字分配给本地char[] - 变量时,该存储在本地分配。

从该范围导出该指针违反了局部变量的(自动)存储持续时间约束并访问指针后面的内存是未定义的行为。

相反,当分配给char*时,会创建指向静态分配字符串的指针,并且不会复制到本地存储。因此,指针在该范围之外保持有效。