Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
填充问题?(C/GCC)_C_Gcc - Fatal编程技术网

填充问题?(C/GCC)

填充问题?(C/GCC),c,gcc,C,Gcc,我正试图将ARM项目(特别是运行Linux2.6.33.3的I.MX27 CPU,使用GCC4.3.2编译)的方法统一到SQLite交互中。作为其中的一部分,我创建了一个带有联合的结构,该联合用于保存要绑定到准备好的语句的值 #define SQLITE_DATA_CHARACTER_STRING_MAX 1024 typedef struct { int data_type; union { int integer; double fl

我正试图将ARM项目(特别是运行Linux2.6.33.3的I.MX27 CPU,使用GCC4.3.2编译)的方法统一到SQLite交互中。作为其中的一部分,我创建了一个带有联合的结构,该联合用于保存要绑定到准备好的语句的值

#define SQLITE_DATA_CHARACTER_STRING_MAX 1024

typedef struct
{
    int data_type;
    union
    {
        int integer;
        double floating_point;
        unsigned char character_string[SQLITE_DATA_CHARACTER_STRING_MAX];
    };
}sqlite_data;
最初,这是
int
float
char
。我想使用
long-long
double
char
。然而,这似乎造成了一个问题。如上所述,以下代码生成可预测的输出:

int data_fields = 15;
int data_fields_index = 0;
sqlite_data data[data_fields];

LogMsg(LOG_INFO, "%s: Assigning", __FUNCTION__);

for(data_fields_index = 0; data_fields_index < data_fields; data_fields_index++)
{
    data[data_fields_index].data_type = (100 + data_fields_index);
    data[data_fields_index].integer = (1000 + data_fields_index);
    LogMsg(LOG_INFO, "%s: data[%d] - %d; type - %d", __FUNCTION__, data_fields_index, data[data_fields_index].integer, data[data_fields_index].data_type);
}
但是,如果我只做一个更改(给
integer
类型
long
),它就会崩溃。因此,以下变化:

typedef struct
{
    int data_type;
    union
    {
        long long integer;
        double floating_point;
        unsigned char character_string[SQLITE_DATA_CHARACTER_STRING_MAX];
    };
}sqlite_data;
生成此输出:

Assigning
data[0] - 1000; type - 0
data[1] - 1001; type - 0
data[2] - 1002; type - 0
data[3] - 1003; type - 0
data[4] - 1004; type - 0
data[5] - 1005; type - 0
data[6] - 1006; type - 0
data[7] - 1007; type - 0
data[8] - 1008; type - 0
data[9] - 1009; type - 0
data[10] - 1010; type - 0
data[11] - 1011; type - 0
data[12] - 1012; type - 0
data[13] - 1013; type - 0
data[14] - 1014; type - 0
我试着用
#pragma pack(6)
对它们进行氘化,并将该数组放入堆中,所有结果都是相同的:
int
有效,
long
无效


这里发生了什么事?

您并不是在告诉
printf()
期待一个
long
。在格式字符串中使用
%lld
,而不是
%d

Sneftel绝对正确。问题是您没有指定
long
,这会导致未定义的行为。要帮助您形象化图片,请执行以下操作:

"%s: data[%d] - %d; type - %d"

%s - [✓] __FUNCTION__ is a valid string.
%d - [✓] data_fields_index is an int
%d - [x] data[data_fields_index].integer is a long long, this will only read 
          the first 4 bytes of an 8 byte integer.
%d - [x] this is likely reading the last 4 bytes of 
          data[data_fields_index].integer which will be 0 for smaller numbers 
          on a little endian architecture.
因此,一个长1000将存储在内存中的little endian中,如下所示:

[0x00 0x20 0x00 0x00 0x00 0x00 0x00 0x00]
  ^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^
      first %d          second %d

将格式更改为
“%s:数据[%d]-%lld;类型-%d”将解决此问题。

长的
打印效果良好。打印为零的是
int type
。@musasabi但可能是您用错误的说明符弄乱了堆栈(它会导致未定义的行为)。因此,请使用
%lld
打印
long
。我添加了一些可能发生的事情的可视化,希望能帮助您理解(这仍然是未定义的行为,因此我们无法100%确定我显示的事情是否发生)。Sneftel和H2CO3是正确的。请注意,除非您的目标是C11。上周在将自定义协议移植到Windows时收到位。您还可以打印出结构的地址,以查看步骤是否随声明更改而更改。这会让你直接看到填充效果。未命名的工会不符合标准,但它们非常便携。我不知道有哪个主流编译器不支持它们作为扩展。平台的端性在这里很重要,基础ABI也很重要。要点是“未定义的行为可以看起来像任何东西——它不是本地化的”。我要感谢你们两位的准确和详细尽管我只能选择一个答案,但我还是投了赞成票。
[0x00 0x20 0x00 0x00 0x00 0x00 0x00 0x00]
  ^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^
      first %d          second %d