简体   繁体   English

为什么此结构用字段中已有的数据初始化?

[英]Why is this struct initialized with data already in a field?

I'm using a library written in C , with my own program that's in C++ . 我正在使用用C编写的库,以及我自己的C ++程序 They typedef a struct like this: 他们像这样键入一个结构:

typedef struct tagCtxt
{
    char     iadl1[50+1];
    char     iadl2[50+1];
    char     iprurb[28+1];
    char     iadl3[50+1];
} PARM;

In one of my methods, I construct it and immediately print the value of one of the fields: 在我的一种方法中,我构造了它并立即打印以下字段之一的值:

PARM parm1;
cout << "'" << parm1.iadl3 << "'" << endl;

As expected, it's blank/empty: 如预期的那样,其为空白/空:

''

Now I do this, creating parm2 : 现在,我这样做,创建parm2

PARM parm1, parm2;
cout << "'" << parm1.iadl3 << "'\t'" << parm2.iadl3 << "'" endl;

Then I get this: 然后我得到这个:

''    'x��'

The output of the second one varies. 第二个的输出变化。 Sometimes it looks like or or ǰ or ǰ , etc. 有时看起来像 ǰǰ等。

This line appears to fix the symptoms: 此行似乎修复症状:

memset(&parm2.iadl3, 0, sizeof(parm2.iadl3));

But what is the problem? 但是有什么问题呢? Why is the char array non-empty for the second one, but not for the first? 为什么第二个字符数组不为空,而第一个字符数组为非空?

Remember, my program is compiled as C++ but the header file I'm using that defines the type is in C . 记住,我的程序被编译为C ++,但是我使用的定义类型的头文件在C中 Does that make a difference? 这有什么区别吗? I'm including the header file like so: 我包括这样的头文件:

extern "C"
{
    #include "parm.h"
}

This is undefined behavior , the initial value of an automatic variable is indeterminate, you need to initialize variables before you use them. 这是未定义的行为自动变量的初始值不确定,使用变量之前需要对其进行初始化。

The C99 draft standard in section 6.2.4 Storage durations of objects says after covering static variables says ( emphasis mine ): C99标准草案的第6.2.4“对象的存储持续时间 ”在覆盖静态变量后说( 重点是 ):

For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. 对于不具有可变长度数组类型的对象,其生存期从进入与之关联的块的时间开始,直到该块的执行以任何方式结束。 [...] The initial value of the object is indeterminate . [...] 对象的初始值是不确定的 [...] [...]

and the definition of indeterminate value is as follows: 不确定值的定义如下:

either an unspecified value or a trap representation 未指定的值或陷阱表示

The C++ draft standard section 8.5 Initializers paragraph 12 says ( emphasis mine ): C ++标准草案8.5节“ 初始化器”12段说( 重点是 ):

If no initializer is specified for an object, the object is default-initialized; 如果未为对象指定初始化程序,则该对象为默认初始化; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value . 如果未执行初始化,则具有自动或动态存储持续时间的对象的值不确定 [ Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2. [注意:具有静态或线程存储持续时间的对象将初始化为零,请参见3.6.2。 —end note ] —尾注]

A good place to get started in understanding some forms of undefined behavior is the Deep C slides. Deep C幻灯片是开始了解某些形式的未定义行为的好地方。

"As expected, it's blank/empty: " No, thats not expected. “按预期,它为空白/空: ”不,那不是预期的。 C++ dones not initialize the value of a variable (Except its data type provides a constructor which does the job, or is a thing with static storage duration). C ++不会初始化变量的值(除了它的数据类型提供了可以完成工作的构造器,或者是具有静态存储持续时间的构造器)。

As Shafik said, reading the uninitialized data has undefined behaviour. 正如Shafik所说,读取未初始化的数据具有不确定的行为。

Doesn't matter with the C/C++ thing. 与C / C ++无关。

In general, memory which you havn't set explicitly (like that memset operation u did) contains undefined values. 通常,您没有显式设置的内存(例如您执行的memset操作)包含未定义的值。

It's not 'expected' to be 0's. 它不是“预期”为0。

C and C++ provides no guarantee regarding values of local variables. C和C ++不保证有关局部变量的值。 They have a garbage values, depending on what is at that memory adress in the moment of allocation. 它们有一个垃圾值,具体取决于分配时该内存的地址。 In order to use them, you must initialize them with a value. 为了使用它们,必须使用一个值初始化它们。

This is not true for global variables. 对于全局变量,情况并非如此。 They are initialized with 0 by default. 默认情况下,它们初始化为0。

char     iadl1[50+1];

Will reserve you a block of memory that are large enough to store 51 characters 将为您保留一块足以存储51个字符的内存

However, it doesn't guarantee you that that block of memory is all empty, it just happens to be empty in your case. 但是,它不能保证您该内存块都是空的,只是您的情况恰好是空的。 In general, use memset to initialize your arrays before accessing it would be the best way to do. 通常,最好使用memset初始化数组,然后再访问它。

memset( iadl1, '\0', sizeof(char)*51);

Only static variables have values pre-initialized. 只有静态变量具有预先初始化的值。 Variables that are created on the stack (ie local variables) have garbage values, and thus should not be used before initializing. 在堆栈上创建的变量(即局部变量)具有垃圾值,因此不应在初始化之前使用它们。

one way is to define a construct function to initialize the params 一种方法是定义一个构造函数来初始化参数

typedef struct tagCtxt
{
    tagCtxt()
    {
     memset( iadl1, '\0', sizeof(char)*51);
     memset( iadl2, '\0', sizeof(char)*51);
     memset( iprurb, '\0', sizeof(char)*29);
     memset( iadl3, '\0', sizeof(char)*51);
    }
    char     iadl1[50+1];
    char     iadl2[50+1];
    char     iprurb[28+1];
    char     iadl3[50+1];
} PARM;

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

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