[英]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;
本來是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);
}
其輸出是這樣的:
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.