簡體   English   中英

填充問題? (C / GCC)

[英]Padding issue? (C / GCC)

我正在嘗試統一一個ARM項目(特別是運行Linux 2.6.33.3的i.MX27 CPU,使用GCC 4.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;

本來是intfloatchar 我想使用long longdoublechar 但是,這似乎引起了問題。 如上所述,以下代碼可產生可預測的輸出:

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

其輸出是這樣的:

 Assigning
 data[0] - 1000; type - 100
 data[1] - 1001; type - 101
 data[2] - 1002; type - 102
 data[3] - 1003; type - 103
 data[4] - 1004; type - 104
 data[5] - 1005; type - 105
 data[6] - 1006; type - 106
 data[7] - 1007; type - 107
 data[8] - 1008; type - 108
 data[9] - 1009; type - 109
 data[10] - 1010; type - 110
 data[11] - 1011; type - 111
 data[12] - 1012; type - 112
 data[13] - 1013; type - 113
 data[14] - 1014; type - 114

但是,如果我只做一個更改(將integer賦予long 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)將它們去unununification,並將該數組放在堆上,所有結果都相同: int有效, long long卻不能。

這里發生了什么?

您不是在告訴printf()期望long long 在格式字符串中使用%lld而不是%d

Sneftel是絕對正確的。 問題是您沒有指定long 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.

因此,只要將long long以小端序形式存儲在內存中,如下所示:

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

將格式更改為"%s: data[%d] - %lld; type - %d" will fix this.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM