c程序如何为局部变量分配内存

时间:2017-02-10 20:51:23

标签: c memory

见下面的简单示例代码:

void printThingWithOne(Set<Thing> things, String one) {
  for(Thing thing : things) {
    if(thing.getOne().equals(one)) {
      System.out.println(thing);
    }
  }
}

输出结果为:

#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;
}

显然,sscanf已经溢出,因此错误地填写了s1和s3中的数据。

检查s1,s2,s3的内存地址,似乎操作系统将其分配如下:

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)

但我将其定义为s1然后s2然后s3,为什么不将内存分配为:

s3 [0x...de,0x...ea]
...garbage data here
s1 [0x...c6,0x...cb]
s2 [0x...c0,0x...c5]

问题:

  1. 为什么s3分配了s1以上的地址?
  2. 为什么在s3和s1之间插入一些数据?

0 个答案:

没有答案