嵌入式学习日记(十四)

2017-07-22

今天是嵌入式学习的第十四天。


今天,有一道内存泄漏的问题,来探讨一下。


  • 程序如下
#include 
#include 


int main()
{
    int i=5;
    char str[6];

    strcpy(str,"abcdefg12"); 

    if(i>100)
    {
        printf("hello!");    //溢出攻击
    }
    else
    {
        printf("no!\n");
    }

    printf("i=%d\n",i);

    return 0;
}

大家是不是以为结果为5?
结果如下所示:

$  ./a.out
hello!
i=3289447

为什么会这样呢?于是我做了一些测试


  • test:
#include 
#include 


int main()
{
  int j=0;
  int i=5;
  char str[6];

  printf("&i=%p\n",&i);

  printf("str=%p\n",str);


  printf("str : ");

  strcpy(str,"abcdefg12");

  for(j=0;j<20;j++)
  {
    printf("%d - %p :  %X  :  %c\n",j,str+j,*(str+j),*(str+j));
  }

  if(i>100)
  {
    printf("hello!\n");
  }
  else
  {
    printf("no\n");
  }

  printf("&i=%p\n",&i);

  printf("i=%X\n",i);

  return 0;
}
  • 执行后结果入下:
&i=0xbfcafa98
str=0xbfcafa92
str : 0 - 0xbfcafa92 :  61  :  a
1 - 0xbfcafa93 :  62  :  b
2 - 0xbfcafa94 :  63  :  c
3 - 0xbfcafa95 :  64  :  d
4 - 0xbfcafa96 :  65  :  e
5 - 0xbfcafa97 :  66  :  f
6 - 0xbfcafa98 :  67  :  g
7 - 0xbfcafa99 :  31  :  1
8 - 0xbfcafa9a :  32  :  2
9 - 0xbfcafa9b :  0  :  
10 - 0xbfcafa9c :  A  :  

11 - 0xbfcafa9d :  0  :  
12 - 0xbfcafa9e :  0  :  
13 - 0xbfcafa9f :  0  :  
14 - 0xbfcafaa0 :  50  :  P
15 - 0xbfcafaa1 :  FFFFFF85  :  �
16 - 0xbfcafaa2 :  4  :  
17 - 0xbfcafaa3 :  8  :  
18 - 0xbfcafaa4 :  70  :  p
19 - 0xbfcafaa5 :  FFFFFF83  :  �
hello!
&i=0xbfcafa98
i=323167

根据之前对strcpy的了解,是把一个字符串强行塞到一个地址开头。所以导致g12\0已经不在字符串中。而我们看到 0xbfcafa98~0xbfcafa9b 地址正好是i所占用的内存地址,而且其中的十六进制的值刚好是“\021g”的十六进制的值。我们提取现象,得到以下两个问题:

1. i在str之前定义,为啥地址在str之后?

2. 为什么 0xbfcafa98~0xbfcafa9b 存储的是’g’,’1’,’2’,’\0’而i的值却是’\0’,’2’,’1’,’g’与实际相反?


解答:

1.定义的局部变量存放在栈区,先定义地址越后。

2.与数据存储的模式有关,大多数的编译器将数据在内存中以小端模式存储。




通过今天的学习,加深了对内存,数据存储的理解。在嵌入式学习中,对这方面的知识尤为重要。

你可能感兴趣的:(嵌入式学习日记(十四))