Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sizeof struct in Go

Tags:

struct

go

sizeof

I'm having a look at Go, which looks quite promising. I am trying to figure out how to get the size of a go struct, for example something like

type Coord3d struct {
    X, Y, Z int64
}

Of course I know that it's 24 bytes, but I'd like to know it programmatically..

Do you have any ideas how to do this ?

like image 663
Jörg Haubrichs Avatar asked Jan 21 '10 23:01

Jörg Haubrichs


People also ask

Can you use sizeof on a struct?

The sizeof for a struct is not always equal to the sum of sizeof of each individual member. This is because of the padding added by the compiler to avoid alignment issues. Padding is only added when a structure member is followed by a member with a larger size or at the end of the structure.

What is a go struct?

A structure or struct in Golang is a user-defined type that allows to group/combine items of possibly different types into a single type. Any real-world entity which has some set of properties/fields can be represented as a struct.

How many bytes is a string in Golang?

In Go Strings are UTF-8 encoded, this means each charcter called rune can be of 1 to 4 bytes long. Here,the charcter ♥ is taking 3 bytes, hence the total length of string is 7.


2 Answers

import unsafe "unsafe"

/* Structure describing an inotify event.  */
type INotifyInfo struct {
    Wd     int32  // Watch descriptor
    Mask   uint32 // Watch mask
    Cookie uint32 // Cookie to synchronize two events
    Len    uint32 // Length (including NULs) of name
}

func doSomething() {
    var info INotifyInfo
    const infoSize = unsafe.Sizeof(info)
    ...
}

NOTE: The OP is mistaken. The unsafe.Sizeof does return 24 on the example Coord3d struct. See comment below.

like image 79
RogerV Avatar answered Oct 07 '22 01:10

RogerV


Roger already showed how to use SizeOf method from the unsafe package. Make sure you read this before relying on the value returned by the function:

The size does not include any memory possibly referenced by x. For instance, if x is a slice, Sizeof returns the size of the slice descriptor, not the size of the memory referenced by the slice.

In addition to this I wanted to explain how you can easily calculate the size of any struct using a couple of simple rules. And then how to verify your intuition using a helpful service.


The size depends on the types it consists of and the order of the fields in the struct (because different padding will be used). This means that two structs with the same fields can have different size.

For example this struct will have a size of 32

struct {
    a bool
    b string
    c bool
}

and a slight modification will have a size of 24 (a 25% difference just due to a more compact ordering of fields)

struct {
    a bool
    c bool
    b string
}

enter image description here enter image description here

As you see from the pictures, in the second example we removed one of the paddings and moved a field to take advantage of the previous padding. An alignment can be 1, 2, 4, or 8. A padding is the space that was used to fill in the variable to fill the alignment (basically wasted space).

Knowing this rule and remembering that:

  • bool, int8/uint8 take 1 byte
  • int16, uint16 - 2 bytes
  • int32, uint32, float32 - 4 bytes
  • int64, uint64, float64, pointer - 8 bytes
  • string - 16 bytes (2 alignments of 8 bytes)
  • any slice takes 24 bytes (3 alignments of 8 bytes). So []bool, [][][]string are the same (do not forget to reread the citation I added in the beginning)
  • array of length n takes n * type it takes of bytes.

Armed with the knowledge of padding, alignment and sizes in bytes, you can quickly figure out how to improve your struct (but still it makes sense to verify your intuition using the service).

like image 45
Salvador Dali Avatar answered Oct 07 '22 00:10

Salvador Dali