Is extra space allocated for variant records? - delphi
I'm working with the variant record below. The variable instance is Kro_Combi. SizeOf(Kro_Combi) reports 7812 bytes. SizeOf(Kro_Combi.data) reports 7810 bytes.
The sum of the SizeOf of all the other data structures composing the "non-directmode" case of the variant record also adds to 7810 bytes.
Why is there a two byte difference? I would like to have the two variant exactly overlay each other.
TKro_Combi = record
case directmode:boolean of
true : (
data : array[0..7809] of byte
);
false : (
Combi_Name : array[0..23] of char; //24
Gap1 : array[0..63] of byte; // 24-87 (64)
Ins_Effect_Group : array[1..12] of TIns_Effect_Params; //74 each, (Ins_Effect_Data=9 bytes) 74*12 = 888
Mast_Effect_Params : array[0..229] of byte; // 976-1205 : 230 bytes
Vect_Aud__Drum_Params : array[0..97] of byte; //1206-1303 : 98 bytes
Karma_Common : array[0..509] of byte; //1304-1813 : 510 bytes
Karma_Module : array[0..3] of TKarma_Module; //1814-2557 : 744 bytes each Total span 1814 - 4789 = 2976 bytes total
Common_Params : array[0..11] of byte; //4790-4801 = 12 bytes
Timbre_Group : array[1..16] of TTimbre_Params; ) // 4802 -4989 = 188 bytes each, 16 Timbres, 4802-7809 = 3008 bytes total for all
end;
First of all, there needs to be space for the directmode field. If you really want the record to have size 7810 bytes then you should remove that field. The other byte will be due to internal alignment and padding of the false part of the variant record. I can't yet quite work out where it comes from. No matter, you simply want to use a packed record to avoid any padding bytes.
TKro_Combi = packed record
case boolean of
true : (
data : array[0..7809] of byte
);
false : (
Combi_Name : array[0..23] of char; //24
Gap1 : array[0..63] of byte; // 24-87 (64)
Ins_Effect_Group : array[1..12] of TIns_Effect_Params; //74 each, (Ins_Effect_Data=9 bytes) 74*12 = 888
Mast_Effect_Params : array[0..229] of byte; // 976-1205 : 230 bytes
Vect_Aud__Drum_Params : array[0..97] of byte; //1206-1303 : 98 bytes
Karma_Common : array[0..509] of byte; //1304-1813 : 510 bytes
Karma_Module : array[0..3] of TKarma_Module; //1814-2557 : 744 bytes each Total span 1814 - 4789 = 2976 bytes total
Common_Params : array[0..11] of byte; //4790-4801 = 12 bytes
Timbre_Group : array[1..16] of TTimbre_Params; ) // 4802 -4989 = 188 bytes each, 16 Timbres, 4802-7809 = 3008 bytes total for all
end;
Related
Finding the Checksum Algorithm in this Serial Communication
Got a brainteaser for you! :) I am working on trying to figuring out this serial communication between a microcontroller and a PC for several months and cannot seem to do it. 9600,N81 and I get no frame errors with my capture tool. Hopefully someone out there can see these samples and it will click with them. Sample 1 337795, IN,0xF0,0x5,0x62,0x0,0x0,0xA2,0xDE,0xF3,0x75,0xF3, Bytes = 9 337862,OUT,0xF0,0x5,0x63,0x0,0x1,0x1,0x2C,0x92,0xF3,0xF0,0xF3, Bytes = 10 338923, IN,0xF0,0x5,0x63,0x0,0x0,0x7E,0x84,0xF3,0x75,0xF3, Bytes = 9 338990,OUT,0xF0,0x5,0x64,0x0,0x1,0x1,0xD,0xC5,0xF3,0xF0,0xF3, Bytes = 10 340051, IN,0xF0,0x5,0x64,0x0,0x0,0x7B,0x8,0xF3,0x75,0xF3, Bytes = 9 340118,OUT,0xF0,0x5,0x65,0x0,0x1,0x1,0xB6,0xD9,0xF3,0xF0,0xF3, Bytes = 10 340499, IN,0xF0,0x0,0x65,0x5,0x3,0x1,0x1,0x0,0xAB,0xD3,0xF3,0x54,0xF3, Bytes = 12 340572,OUT,0xF0,0x5,0x66,0x0,0x1,0x1,0x7B,0xFC,0xF3,0xF0,0x5,0x66,0x3,0x4,0x4,0x1,0x8,0x3,0x2F,0x9E,0xF3,0xF3, Bytes = 21 340665, IN,0xF0,0x5,0x66,0x0,0x0,0xC3,0xBD,0xF3,0xAB,0xF3, Bytes = 9 340731,OUT,0xF0,0x5,0x67,0x0,0x1,0x1,0xC0,0xE0,0xF3,0xF0,0xF3, Bytes = 10 341794, IN,0xF0,0x5,0x67,0x0,0x0,0x1F,0xE7,0xF3,0xAB,0xF3, Bytes = 9 341860,OUT,0xF0,0x5,0x68,0x0,0x1,0x1,0x39,0x52,0xF3,0xF0,0xF3, Bytes = 10 342923, IN,0xF0,0x5,0x68,0x0,0x0,0xD8,0xAD,0xF3,0xAB,0xF3, Bytes = 9 342989,OUT,0xF0,0x5,0x69,0x0,0x1,0x1,0x82,0x4E,0xF3,0xF0,0xF3, Bytes = 10 344052, IN,0xF0,0x5,0x69,0x0,0x0,0x4,0xF7,0xF3,0xAB,0xF3, Bytes = 9 344118,OUT,0xF0,0x5,0x6A,0x0,0x1,0x1,0x4F,0x6B,0xF3,0xF0,0xF3, Bytes = 10 345180, IN,0xF0,0x5,0x6A,0x0,0x0,0x60,0x18,0xF3,0xAB,0xF3, Bytes = 9 345246,OUT,0xF0,0x5,0x6B,0x0,0x1,0x1,0xF4,0x77,0xF3,0xF0,0xF3, Bytes = 10 345627, IN,0xF0,0x0,0x6B,0x5,0x3,0x1,0x1,0x0,0x9,0xEA,0xF3,0x54,0xF3, Bytes = 12 345700,OUT,0xF0,0x5,0x6C,0x0,0x1,0x1,0xD5,0x20,0xF3,0xF0,0x5,0x6C,0x3,0x4,0x4,0x1,0x8,0x3,0x78,0x77,0xF3,0xF3, Bytes = 21 Sample 2 371435, IN,0xF0,0x5,0x8C,0x0,0x0,0x18,0xC7,0xF3,0x1A,0xF3, Bytes = 9 371502,OUT,0xF0,0x5,0x8D,0x0,0x1,0x1,0xE4,0x88,0xF3,0xF0,0xF3, Bytes = 10 372563, IN,0xF0,0x5,0x8D,0x0,0x0,0xC4,0x9D,0xF3,0x1A,0xF3, Bytes = 9 372630,OUT,0xF0,0x5,0x8E,0x0,0x1,0x1,0x29,0xAD,0xF3,0xF0,0xF3, Bytes = 10 373692, IN,0xF0,0x5,0x8E,0x0,0x0,0xA0,0x72,0xF3,0x1A,0xF3, Bytes = 9 373758,OUT,0xF0,0x5,0x8F,0x0,0x1,0x1,0x92,0xB1,0xF3,0xF0,0xF3, Bytes = 10 374820, IN,0xF0,0x5,0x8F,0x0,0x0,0x7C,0x28,0xF3,0x1A,0xF3, Bytes = 9 374887,OUT,0xF0,0x5,0x90,0x0,0x1,0x1,0xCA,0xC0,0xF3,0xF0,0xF3, Bytes = 10 375949, IN,0xF0,0x5,0x90,0x0,0x0,0x2E,0xE7,0xF3,0x1A,0xF3, Bytes = 9 376015,OUT,0xF0,0x5,0x91,0x0,0x1,0x1,0x71,0xDC,0xF3,0xF0,0xF3, Bytes = 10 376396, IN,0xF0,0x0,0x91,0x5,0x3,0x1,0x1,0x0,0xA4,0x3,0xF3,0xFD,0xF3, Bytes = 12 376469,OUT,0xF0,0x5,0x92,0x0,0x1,0x1,0xBC,0xF9,0xF3,0xF0,0x5,0x92,0x3,0x4,0x4,0x1,0x8,0x3,0x8,0x66,0xF3,0xF3, Bytes = 21 376562, IN,0xF0,0x5,0x92,0x0,0x0,0x96,0x52,0xF3,0xA4,0xF3, Bytes = 9 376628,OUT,0xF0,0x5,0x93,0x0,0x1,0x1,0x7,0xE5,0xF3,0xF0,0xF3, Bytes = 10 377692, IN,0xF0,0x5,0x93,0x0,0x0,0x4A,0x8,0xF3,0xA4,0xF3, Bytes = 9 377758,OUT,0xF0,0x5,0x94,0x0,0x1,0x1,0x26,0xB2,0xF3,0xF0,0xF3, Bytes = 10 378820, IN,0xF0,0x5,0x94,0x0,0x0,0x4F,0x84,0xF3,0xA4,0xF3, Bytes = 9 378887,OUT,0xF0,0x5,0x95,0x0,0x1,0x1,0x9D,0xAE,0xF3,0xF0,0xF3, Bytes = 10 379949, IN,0xF0,0x5,0x95,0x0,0x0,0x93,0xDE,0xF3,0xA4,0xF3, Bytes = 9 380015,OUT,0xF0,0x5,0x96,0x0,0x1,0x1,0x50,0x8B,0xF3,0xF0,0xF3, Bytes = 10 381077, IN,0xF0,0x5,0x96,0x0,0x0,0xF7,0x31,0xF3,0xA4,0xF3, Bytes = 9 381144,OUT,0xF0,0x5,0x97,0x0,0x1,0x1,0xEB,0x97,0xF3,0xF0,0xF3, Bytes = 10 381523, IN,0xF0,0x0,0x97,0x5,0x3,0x1,0x1,0x0,0x5E,0x1B,0x5B,0xF3,0xF3, Bytes = 12 I have more, if desired. Some observations I've been able to see - First, the numbers at the begging are aggregate timings in I think nanoseconds. The 33* is 33 seconds. Beginning byte 0xF0 Ending byte 0xF3 Sequence byte, the third byte of every packet increments by 1 It seems the destination device (noted as OUT) increments first and the host (noted as IN) follows.. For the most part OUT packets are 10 bytes and IN packets are 9 bytes. There are some times when this is not true and the packet can be 21 bytes.. Although I do notice a begin byte and end byte next to each other in the string of 21 bytes, the third byte (sequence#) does not increment. I am not sure how to understand these longer packets. This is a point to point communication, there are no other devices connected between these 2. It is very chatty. During my testing and probing, my test leads slipped between a couple of pins and killed the microcontroller. Thinking it would be a great project (and it is), I am attempting to recreate the functions of the original microcontroller. Which, I pretty much have done with the exception of the communication, figuring out what they are talking about and the checksum. I assume the second to the last byte is the checksum. Thank you!
By omitting the begin (0xF0) and end (0xF3) bytes, Reversed CRC-CCITT is used to calculate the checksum. Thanks to this website, I pasted in the bytes and found it - https://www.scadacore.com/tools/programming-calculators/online-checksum-calculator/
Decode UDP message with LUA
I'm relatively new to lua and programming in general (self taught), so please be gentle! Anyway, I wrote a lua script to read a UDP message from a game. The structure of the message is: DATAxXXXXaaaaBBBBccccDDDDeeeeFFFFggggHHHH DATAx = 4 letter ID and x = control character XXXX = integer shows the group of the data (groups are known) aaaa...HHHHH = 8 single-precision floating point numbers The last ones is those numbers I need to decode. If I print the message as received, it's something like: DATA*{V???A?A?...etc. Using string.byte(), I'm getting a stream of bytes like this (I have "formatted" the bytes to reflect the structure above. 68 65 84 65/42/20 0 0 0/237 222 28 66/189 59 182 65/107 42 41 65/33 173 79 63/0 0 128 63/146 41 41 65/0 0 30 66/0 0 184 65 The first 5 bytes are of course the DATA*. The next 4 are the 20th group of data. The next bytes, the ones I need to decode, and are equal to those values: 237 222 28 66 = 39.218 189 59 182 65 = 22.779 107 42 41 65 = 10.573 33 173 79 63 = 0.8114 0 0 128 63 = 1.0000 146 41 41 65 = 10.573 0 0 30 66 = 39.500 0 0 184 65 = 23.000 I've found C# code that does the decode with BitConverter.ToSingle(), but I haven't found any like this for Lua. Any idea?
What Lua version do you have? This code works in Lua 5.3 local str = "DATA*\20\0\0\0\237\222\28\66\189\59\182\65..." -- Read two float values starting from position 10 in the string print(string.unpack("<ff", str, 10)) --> 39.217700958252 22.779169082642 18 -- 18 (third returned value) is the next position in the string For Lua 5.1 you have to write special function (or steal it from François Perrad's git repo ) local function binary_to_float(str, pos) local b1, b2, b3, b4 = str:byte(pos, pos+3) local sign = b4 > 0x7F and -1 or 1 local expo = (b4 % 0x80) * 2 + math.floor(b3 / 0x80) local mant = ((b3 % 0x80) * 0x100 + b2) * 0x100 + b1 local n if mant + expo == 0 then n = sign * 0.0 elseif expo == 0xFF then n = (mant == 0 and sign or 0) / 0 else n = sign * (1 + mant / 0x800000) * 2.0^(expo - 0x7F) end return n end local str = "DATA*\20\0\0\0\237\222\28\66\189\59\182\65..." print(binary_to_float(str, 10)) --> 39.217700958252 print(binary_to_float(str, 14)) --> 22.779169082642
It’s little-endian byte-order of IEEE-754 single-precision binary: E.g., 0 0 128 63 is: 00111111 10000000 00000000 00000000 (63) (128) (0) (0) Why that equals 1 requires that you understand the very basics of IEEE-754 representation, namely its use of an exponent and mantissa. See here to start. See #Egor‘s answer above for how to use string.unpack() in Lua 5.3 and one possible implementation you could use in earlier versions.
Getting the stack pointer content using Intel's PinTool
Using objdump utility, we are able to retrieved the relative address of a variable for example consider a simple C program: Source-code: #include<stdio.h> void do_stuff(int my_arg){ int my_local=my_arg+2; int i; for(i=0;i<my_local;i++) printf("i=%d\n",i); } int main(){ do_stuff(2); return 0; } Compile with gcc : $ gcc -g example.c -o example Run objdump utility with dwarf flag for ELF information. $objdump --dwarf=info example Output: Contents of the .debug_info section: Compilation Unit # offset 0x0: Length: 0xd3 (32-bit) Version: 4 Abbrev Offset: 0x0 Pointer Size: 8 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit) <c> DW_AT_producer : (indirect string, offset: 0x0): GNU C 4.8.4 -mtune=generic -march=x86-64 -g -fstack-protector <10> DW_AT_language : 1 (ANSI C) <11> DW_AT_name : (indirect string, offset: 0xcd): sample1.c <15> DW_AT_comp_dir : (indirect string, offset: 0x7e): /home/bernard/PhD/TEJAS/tejas_installation_kit/Tejas-Simulator/Tejas/benchmark <19> DW_AT_low_pc : 0x40052d <21> DW_AT_high_pc : 0x54 <29> DW_AT_stmt_list : 0x0 <1><2d>: Abbrev Number: 2 (DW_TAG_base_type) <2e> DW_AT_byte_size : 8 <2f> DW_AT_encoding : 7 (unsigned) <30> DW_AT_name : (indirect string, offset: 0x47): long unsigned int <1><34>: Abbrev Number: 2 (DW_TAG_base_type) <35> DW_AT_byte_size : 1 <36> DW_AT_encoding : 8 (unsigned char) <37> DW_AT_name : (indirect string, offset: 0x62): unsigned char <1><3b>: Abbrev Number: 2 (DW_TAG_base_type) <3c> DW_AT_byte_size : 2 <3d> DW_AT_encoding : 7 (unsigned) <3e> DW_AT_name : (indirect string, offset: 0xde): short unsigned int <1><42>: Abbrev Number: 2 (DW_TAG_base_type) <43> DW_AT_byte_size : 4 <44> DW_AT_encoding : 7 (unsigned) <45> DW_AT_name : (indirect string, offset: 0x4c): unsigned int <1><49>: Abbrev Number: 2 (DW_TAG_base_type) <4a> DW_AT_byte_size : 1 <4b> DW_AT_encoding : 6 (signed char) <4c> DW_AT_name : (indirect string, offset: 0x64): signed char <1><50>: Abbrev Number: 2 (DW_TAG_base_type) <51> DW_AT_byte_size : 2 <52> DW_AT_encoding : 5 (signed) <53> DW_AT_name : (indirect string, offset: 0xf1): short int <1><57>: Abbrev Number: 3 (DW_TAG_base_type) <58> DW_AT_byte_size : 4 <59> DW_AT_encoding : 5 (signed) <5a> DW_AT_name : int <1><5e>: Abbrev Number: 2 (DW_TAG_base_type) <5f> DW_AT_byte_size : 8 <60> DW_AT_encoding : 5 (signed) <61> DW_AT_name : (indirect string, offset: 0x75): long int <1><65>: Abbrev Number: 2 (DW_TAG_base_type) <66> DW_AT_byte_size : 8 <67> DW_AT_encoding : 7 (unsigned) <68> DW_AT_name : (indirect string, offset: 0xfb): sizetype <1><6c>: Abbrev Number: 2 (DW_TAG_base_type) <6d> DW_AT_byte_size : 1 <6e> DW_AT_encoding : 6 (signed char) <6f> DW_AT_name : (indirect string, offset: 0x6b): char <1><73>: Abbrev Number: 4 (DW_TAG_subprogram) <74> DW_AT_external : 1 <74> DW_AT_name : (indirect string, offset: 0x59): do_stuff <78> DW_AT_decl_file : 1 <79> DW_AT_decl_line : 2 <7a> DW_AT_prototyped : 1 <7a> DW_AT_low_pc : 0x40052d <82> DW_AT_high_pc : 0x3f <8a> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <8c> DW_AT_GNU_all_tail_call_sites: 1 <8c> DW_AT_sibling : <0xb9> <2><90>: Abbrev Number: 5 (DW_TAG_formal_parameter) <91> DW_AT_name : (indirect string, offset: 0xd7): my_arg <95> DW_AT_decl_file : 1 <96> DW_AT_decl_line : 2 <97> DW_AT_type : <0x57> <9b> DW_AT_location : 2 byte block: 91 5c (DW_OP_fbreg: -36) <2><9e>: Abbrev Number: 6 (DW_TAG_variable) <9f> DW_AT_name : (indirect string, offset: 0x3e): my_local <a3> DW_AT_decl_file : 1 <a4> DW_AT_decl_line : 3 <a5> DW_AT_type : <0x57> <a9> DW_AT_location : 2 byte block: 91 6c (DW_OP_fbreg: -20) <2><ac>: Abbrev Number: 7 (DW_TAG_variable) <ad> DW_AT_name : i <af> DW_AT_decl_file : 1 <b0> DW_AT_decl_line : 4 <b1> DW_AT_type : <0x57> <b5> DW_AT_location : 2 byte block: 91 68 (DW_OP_fbreg: -24) <2><b8>: Abbrev Number: 0 <1><b9>: Abbrev Number: 8 (DW_TAG_subprogram) <ba> DW_AT_external : 1 <ba> DW_AT_name : (indirect string, offset: 0x70): main <be> DW_AT_decl_file : 1 <bf> DW_AT_decl_line : 9 <c0> DW_AT_type : <0x57> <c4> DW_AT_low_pc : 0x40056c <cc> DW_AT_high_pc : 0x15 <d4> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <d6> DW_AT_GNU_all_tail_call_sites: 1 <1><d6>: Abbrev Number: 0 I want to do as follows:- I want to retrieved the address of a variable , say my_local. First I will look into DW_TAG_Variable, then DW_AT_name, DW_AT_location which was given by base register at function -20 from the top. Question: How to know the content of base register at run time. Can we implement it using PinTool. Question in broader sense: I want variable my_local map to which address in memory given information from dwarf and Pintool. Thanks in Advance.
You should be able to use Pin's SafeCopy function to access app memory and copy it into pintool memory. But as noted in the comments, it's not always possible to know where variable values are stored reliably so keep this in mind.
Delphi Set Invalid Typecast
How do I fix this invalid typecast error? The code works when the set has less than 31 items. Below is the code snippet: type TOptionsSurveyTypes=( ostLoadSurvey00, ostLoadSurvey01, ostLoadSurvey02, ostLoadSurvey03, ostLoadSurvey04, ostLoadSurvey05, ostLoadSurvey06, ostLoadSurvey07, ostLoadSurvey08, ostLoadSurvey09, ostLoadSurvey10, ostEventLog01, ostEventLog02, ostEventLog03, ostEventLog04, ostEventLog05, ostSagSwell, ostTamper, ostWaveforms, ostDeviceList, ostDeleteData, ostTOUBillingTotal, ostTOUPrevious, ostProfileGenericLoadSurvey01, ostProfileGenericLoadSurvey02, ostProfileGenericLoadSurvey03, ostProfileGenericLoadSurvey04, ostProfileGenericLoadSurvey05, ostProfileGenericLoadSurvey06, ostProfileGenericLoadSurvey07, ostProfileGenericLoadSurvey08, ostProfileGenericLoadSurvey09, ostProfileGenericLoadSurvey10, ostProfileGenericEventLog01, ostProfileGenericEventLog02, ostProfileGenericEventLog03, ostProfileGenericEventLog04, ostProfileGenericEventLog05, ostProfileGenericBillingTotal, ostProfileGenericPrevious, ostProfileGeneric ); TOptionsSurveyTypesSet=set of TOptionsSurveyTypes; function TUserProcessRollback.SurveyRollBack:boolean; var vRollbackDate: TDateTime; FOptions: LongWord; begin ... if ostDeleteData in TOptionsSurveyTypesSet(FOptions) then <-- invalid typecast error here vRollbackDate := 0.00 else vRollbackDate := FRollbackDate; ... end; When I reduce the set to just less than 32 items and FOptions is declared as DWORD, the code compiles . Thanks
Your enumerated type has 41 items. Each byte holds 8 bits. To have a set of this enumerated type requires at least 41 bits. The smallest number of bytes necessary to hold 41 bits is 6. So the set type is 6 bytes. To confirm this, you can execute this: ShowMessage ( inttostr ( sizeof ( TOptionsSurveyTypesSet ) ) ); A DWORD is 4 bytes, so it cannot be typecast into a type that is 6 bytes. If you declare fOptions to be a type with 6 bytes, your code will compile. FOptions: packed array [ 1 .. 6] of byte; If you reduce the enumerated type to 32 or fewer items, then the set type will be 4 bytes, and so the typecast from DWORD will work.
Golang append memory allocation VS. STL push_back memory allocation
I compared the Go append function and the STL vector.push_back and found that different memory allocation strategy which confused me. The code is as follow: // CPP STL code void getAlloc() { vector<double> arr; int s = 9999999; int precap = arr.capacity(); for (int i=0; i<s; i++) { if (precap < i) { arr.push_back(rand() % 12580 * 1.0); precap = arr.capacity(); printf("%d %p\n", precap, &arr[0]); } else { arr.push_back(rand() % 12580 * 1.0); } } printf("\n"); return; } // Golang code func getAlloc() { arr := []float64{} size := 9999999 pre := cap(arr) for i:=0; i<size; i++ { if pre < i { arr = append(arr, rand.NormFloat64()) pre = cap(arr) log.Printf("%d %p\n", pre, &arr) } else { arr = append(arr, rand.NormFloat64()) } } return; } But the memory address is invarient to the increment of size expanding, this really confused me. By the way, the memory allocation strategy is different in this two implemetation (STL VS. Go), I mean the expanding size. Is there any advantage or disadvantage? Here is the simplified output of code above[size and first element address]: Golang CPP STL 2 0xc0800386c0 2 004B19C0 4 0xc0800386c0 4 004AE9B8 8 0xc0800386c0 6 004B29E0 16 0xc0800386c0 9 004B2A18 32 0xc0800386c0 13 004B2A68 64 0xc0800386c0 19 004B2AD8 128 0xc0800386c0 28 004B29E0 256 0xc0800386c0 42 004B2AC8 512 0xc0800386c0 63 004B2C20 1024 0xc0800386c0 94 004B2E20 1280 0xc0800386c0 141 004B3118 1600 0xc0800386c0 211 004B29E0 2000 0xc0800386c0 316 004B3080 2500 0xc0800386c0 474 004B3A68 3125 0xc0800386c0 711 004B5FD0 3906 0xc0800386c0 1066 004B7610 4882 0xc0800386c0 1599 004B9768 6102 0xc0800386c0 2398 004BC968 7627 0xc0800386c0 3597 004C1460 9533 0xc0800386c0 5395 004B5FD0 11916 0xc0800386c0 8092 004C0870 14895 0xc0800386c0 12138 004D0558 18618 0xc0800386c0 18207 004E80B0 23272 0xc0800386c0 27310 0050B9B0 29090 0xc0800386c0 40965 004B5FD0 36362 0xc0800386c0 61447 00590048 45452 0xc0800386c0 92170 003B0020 56815 0xc0800386c0 138255 00690020 71018 0xc0800386c0 207382 007A0020 .... UPDATE: See comments for Golang memory allocation strategy. For STL, the strategy depends on the implementation. See this post for further information.
Your Go and C++ code fragments are not equivalent. In the C++ function, you are printing the address of the first element in the vector, while in the Go example you are printing the address of the slice itself. Like a C++ std::vector, a Go slice is a small data type that holds a pointer to an underlying array that holds the data. That data structure has the same address throughout the function. If you want the address of the first element in the slice, you can use the same syntax as in C++: &arr[0].
You're getting the pointer to the slice header, not the actual backing array. You can think of the slice header as a struct like type SliceHeader struct { len,cap int backingArray unsafe.Pointer } When you append and the backing array is reallocated, the pointer backingArray will likely be changed (not necessarily, but probably). However, the location of the struct holding the length, cap, and pointer to the backing array doesn't change -- it's still on the stack right where you declared it. Try printing &arr[0] instead of &arr and you should see behavior closer to what you expect. This is pretty much the same behavior as std::vector, incidentally. Think of a slice as closer to a vector than a magic dynamic array.