简体   繁体   English

为什么传递char []不起作用,但是(不建议使用的转换)char *起作用?

[英]why does passing char[] not work, but (deprecated conversion) char* does?

I cannot explain myself the reason for the following behaviour. 我无法解释以下行为的原因。 I initialize two pieces of text, one as char*, the other as char[] and put them into a structure. 我初始化了两段文本,一个为char *,另一个为char []并将它们放入一个结构中。 Both appear fine in the structure, but back in main, the second one is lost, and the first gives me a compiler warning which i understand (deprecated conversion from string constant to char*). 两者在结构上看起来都不错,但是在main中,第二个丢失了,第一个给了我我理解的编译器警告(不建议将其从字符串常量转换为char *)。

This is the first question I ask here, and I apologize for anything done wrong. 这是我在这里提出的第一个问题,对于任何做错的事情,我深表歉意。 And yes, I tried to search, but related to char* and char[], there appear a lot of Q&A, none I found similar to the nested problem I am having. 是的,我尝试搜索,但是与char *和char []有关,出现了很多问答,没有发现与我遇到的嵌套问题类似的问题。

From the attached code I get the output: 从附带的代码中,我得到输出:

get_struct: 5 test test2
main: 5 test

(the test2 at the end missing) (最后的test2丢失了)

So the code: 所以代码:

    #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;
    }

You have a problem in that you store pointers to local variables in the structure. 您有一个问题,就是在结构中存储了指向局部变量的指针。

In the case of the test_char2 array, it no longer exists once the get_struct function returns. 对于test_char2数组,一旦get_struct函数返回,该数组就不再存在。 This means that the pointer a_char2 no longer points to a valid string, and dereferencing this pointer is undefined behavior. 这意味着指针a_char2不再指向有效的字符串,并且取消引用该指针是未定义的行为。

The reason the first pointer works, is because it doesn't point to a local variable, it points to a string literal, and those are stored elsewhere in memory. 第一个指针起作用的原因是,它没有指向局部变量,而是指向字符串文字,并且这些指针存储在内存中的其他位置。

When coding in C++, there is no longer a reason to use pointers or arrays for string, instead use the std::string class. 使用C ++进行编码时,不再有理由使用指针或数组作为字符串,而不必使用std::string类。

char* test_char1 = "test";

This creates a pointer to a string literal. 这将创建一个指向字符串文字的指针。 String literals are const but, for historical reasons, the language allows the pointer to be non- const ; 字符串文字是const但是由于历史原因,该语言允许指针为非const however, this is deprecated, hence the warning. 但是,不建议这样做,因此发出警告。 If you attempt to modify the string, then you'll get undefined behaviour. 如果您尝试修改字符串,则将获得未定义的行为。

char test_char2[] = "test2";

This creates a local array, initialised by copying a string literal. 这将创建一个本地数组,通过复制字符串文字进行初始化。 It is not const , so you can modify it if you like. 它不是const ,因此您可以根据需要进行修改。 But once the function returns, this is destroyed, so your structure ends up with a dangling pointer to invalid memory. 但是一旦函数返回,它就会被销毁,因此您的结构最终将带有指向无效内存的悬空指针 That is why you get undefined behaviour when you try to print it in main . 这就是为什么尝试在main打印时会出现未定义行为的原因。

Two pieces of advice: 两个建议:

  • Don't use C-style character arrays and pointers to represent strings; 不要使用C样式的字符数组和指针来表示字符串; use std::string . 使用std::string That manages memory for you, avoiding the lifetime issues you're encountering here. 这样可以为您管理内存,避免您在此遇到的生命周期问题。
  • If you really want to mess around with arrays and pointers, use const char* unless you actually need to modify it. 如果您真的想弄乱数组和指针,请使用const char*除非您确实需要修改它。 Otherwise, it's difficult to work with string literals. 否则,很难处理字符串文字。

When assigning a string literal to a local char[] -variable, that storage is allocated locally. 将字符串文字分配给本地char[]变量时,该存储将在本地分配。

Exporting that pointer from that scope violates the (automatic) storage duration constraints of the local variable and accessing the memory behind the pointer is undefined behaviour. 从该范围中导出该指针违反了局部变量的(自动)存储持续时间约束,并且访问指针后面的内存是未定义的行为。

In contrast, when assigning to char* , a pointer to a statically allocated string is created and no copying to local storage takes place. 相反,当分配给char* ,将创建指向静态分配的字符串的指针,并且不会复制到本地存储。 Thus, the pointer remains valid outside that scope. 因此,指针在该范围之外仍然有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM