See below simple example code:
#include <stdio.h>
void dumpmem(unsigned char* p,int len,const char* desc) {
printf("\nvar:%s\n",desc);
printf("content:%s\n",p);
p = p + len - 1;
for (int i=0;i<len;i++) {
printf("----%p -> %c(%02x)\n",p,*p,*p);
p--;
}
}
#define SIZE 6
int main(void) {
unsigned char s1[SIZE];
unsigned char s2[SIZE];
unsigned char s3[27] = "abcdefghijklmnopqrstuvwxyz";
unsigned char* p = (unsigned char*)&s1;
unsigned char* q = (unsigned char*)(&s1+1);
dumpmem(s3,27,"s3");
sscanf((const char*)s3,"%s",s2);
dumpmem(s1,SIZE,"s1");
dumpmem(s2,SIZE,"s2");
dumpmem(s3,27,"s3");
return 0;
}
The output is:
var:s3
content:abcdefghijklmnopqrstuvwxyz
----0x7fff5bcc66ea -> (00)
----0x7fff5bcc66e9 -> z(7a)
----0x7fff5bcc66e8 -> y(79)
----0x7fff5bcc66e7 -> x(78)
----0x7fff5bcc66e6 -> w(77)
----0x7fff5bcc66e5 -> v(76)
----0x7fff5bcc66e4 -> u(75)
----0x7fff5bcc66e3 -> t(74)
----0x7fff5bcc66e2 -> s(73)
----0x7fff5bcc66e1 -> r(72)
----0x7fff5bcc66e0 -> q(71)
----0x7fff5bcc66df -> p(70)
----0x7fff5bcc66de -> o(6f)
----0x7fff5bcc66dd -> n(6e)
----0x7fff5bcc66dc -> m(6d)
----0x7fff5bcc66db -> l(6c)
----0x7fff5bcc66da -> k(6b)
----0x7fff5bcc66d9 -> j(6a)
----0x7fff5bcc66d8 -> i(69)
----0x7fff5bcc66d7 -> h(68)
----0x7fff5bcc66d6 -> g(67)
----0x7fff5bcc66d5 -> f(66)
----0x7fff5bcc66d4 -> e(65)
----0x7fff5bcc66d3 -> d(64)
----0x7fff5bcc66d2 -> c(63)
----0x7fff5bcc66d1 -> b(62)
----0x7fff5bcc66d0 -> a(61)
var:s1
content:ghijklmnopqrstuvwxyz
----0x7fff5bcc66cb -> l(6c)
----0x7fff5bcc66ca -> k(6b)
----0x7fff5bcc66c9 -> j(6a)
----0x7fff5bcc66c8 -> i(69)
----0x7fff5bcc66c7 -> h(68)
----0x7fff5bcc66c6 -> g(67)
var:s2
content:abcdefghijklmnopqrstuvwxyz
----0x7fff5bcc66c5 -> f(66)
----0x7fff5bcc66c4 -> e(65)
----0x7fff5bcc66c3 -> d(64)
----0x7fff5bcc66c2 -> c(63)
----0x7fff5bcc66c1 -> b(62)
----0x7fff5bcc66c0 -> a(61)
var:s3
content:qrstuvwxyz
----0x7fff5bcc66ea -> (00)
----0x7fff5bcc66e9 -> z(7a)
----0x7fff5bcc66e8 -> y(79)
----0x7fff5bcc66e7 -> x(78)
----0x7fff5bcc66e6 -> w(77)
----0x7fff5bcc66e5 -> v(76)
----0x7fff5bcc66e4 -> u(75)
----0x7fff5bcc66e3 -> t(74)
----0x7fff5bcc66e2 -> s(73)
----0x7fff5bcc66e1 -> r(72)
----0x7fff5bcc66e0 -> q(71)
----0x7fff5bcc66df -> p(70)
----0x7fff5bcc66de -> o(6f)
----0x7fff5bcc66dd -> n(6e)
----0x7fff5bcc66dc -> m(6d)
----0x7fff5bcc66db -> l(6c)
----0x7fff5bcc66da -> (00)
----0x7fff5bcc66d9 -> z(7a)
----0x7fff5bcc66d8 -> y(79)
----0x7fff5bcc66d7 -> x(78)
----0x7fff5bcc66d6 -> w(77)
----0x7fff5bcc66d5 -> v(76)
----0x7fff5bcc66d4 -> u(75)
----0x7fff5bcc66d3 -> t(74)
----0x7fff5bcc66d2 -> s(73)
----0x7fff5bcc66d1 -> r(72)
----0x7fff5bcc66d0 -> q(71)
Obviously, sscanf has overflow so data filled in s1 and s3 wrongly.
Check the memory address for s1,s2,s3, it seems OS assign it as below:
s3 [0x...de,0x...ea]
...garbage data here
s1 [0x...c6,0x...cb]
s2 [0x...c0,0x...c5]
But I define it as s1 then s2 then s3, why not it assign memory as:
s1 [0x...c6,0x...cb]
s2 [0x...c0,0x...c5]
s3 [0x...a5,0x...bf]
Questions:
- Why s3 assigned address above s1?
- Why some data inserted between s3 and s1?