JoseJimRin
JoseJimRin

Reputation: 402

Initialize typedef struct by attribute problem

I defined an struct based on bytes, with size of 3 bytes. (1 packetID and 2 packetSize) I checked the size with sizeof function, and it works well:

#pragma pack(1)

typedef struct ENVIRONMENT_STRUCT{
    unsigned char packetID[1];
    unsigned char packetSize[2];
}

I created a variable and reserved memory like this:

ENVIRONMENT_STRUCT * environment_struct = new ENVIRONMENT_STRUCT();

For now I want to initialize environment_struct.

The problem is about I am trying to initialize this struct by attribute, just like this:

*environment_struct->packetSize = 100;

But when I checked this value, using:

std::cout << "Packet Size: " << environment_struct->packetSize << endl;

Result: Packet Size: d

Expected result: Packet Size: 100

If i will work with numbers, Should I define the struct using csdint library? For example, u_int8 and this type of variable.

Upvotes: 0

Views: 264

Answers (4)

Ian
Ian

Reputation: 1251

As packetSize is declared as char-type, it's being output as a character. (ASCII code of character 'd' is 100...)

Try casting it to an integer-type:

std::cout << "Packet Size: " << (int)environment_struct->packetSize << endl;

Alternatively, since you appear to want to store the number as a 2-byte type, you could avoid such casting and simply declare packetSize as unsigned short. This will be interpreted by cout as an integer-type.

Upvotes: 0

Igor Pchelnikov
Igor Pchelnikov

Reputation: 31

You get this result as you tries to print a character symbol not an integer.

To fix it just cast the value or declare it as integer depending on your needs.

Cast example:

std::cout << "Packet Size: " << static_cast<int>(*environment_struct->packetSize) << std::endl;

Upvotes: 0

eerorika
eerorika

Reputation: 238311

Let's first consider what *environment_struct->packetSize = 100; does. It sets the first byte of ENVIRONMENT_STRUCT::packetSize to 100. A more conventional syntax to do this is: environment_struct->packetSize[0] = 100.

There's really no way to initialize the struct in a way for the expression std::cout << environment_struct->packetSize to result in the output of 100. Let us consider what that does. environment_struct->packetSize is an array, which in this case decays to a pointer to first element. Character pointers inserted into character streams are interpreted as null terminated character strings. Luckily, you had valueinitialized the second byte of environment_struct->packetSize, so your array is indeed null terminated. The value of the first byte is interpreted as an encoded character. On your system encoding, it happens that d character is encoded as value 100.

If you wish to print the numeric value of the first byte of environment_struct->packetSize, which you had set to 100, you can use:

std::cout << "Packet Size: " << (int)environment_struct->packetSize[0] << endl;

Upvotes: 1

NathanOliver
NathanOliver

Reputation: 180490

When you do

ENVIRONMENT_STRUCT * environment_struct = new ENVIRONMENT_STRUCT();

you initialize packetSize to be {0, 0}. Then

*environment_struct->packetSize = 100;

turns the array into {100, 0}. Since the array is a character array when you send it to cout with

std::cout << "Packet Size: " << environment_struct->packetSize << endl;

it treats it as a c-string and prints out the string contents. Since you see d that means your system is using ascii as the character 'd' has an integer representation of 100. To see the 100 you need to cast it to an int like

std::cout << "Packet Size: " << static_cast<int>(*environment_struct->packetSize) << endl;

Do note that since packetSize is an array of two chars you can't actually assign a single value that takes up that whole space. If you want this then you need to use fixed width types like

typedef struct ENVIRONMENT_STRUCT{
    uint8_t packetID; // unsigned integer that is exactly 8 bits wide.  Will be a compiler error if it does not exist
    uint16_t packetSize; // unsigned integer that is exactly 16 bits wide.  Will be a compiler error if it does not exist
};

int main()
{
    ENVIRONMENT_STRUCT * environment_struct = new ENVIRONMENT_STRUCT();
    environment_struct->packetSize = 100;
    std::cout << "Packet Size: " << environment_struct->packetSize << std::endl;
}

Upvotes: 3

Related Questions