C语言-非法内存操作分析

•结构体成员指针未初始化

•没有为结构体指针分配足够的内存空间

struct Demo
{
  int* p;
};

int main()
{
  struct Demo d1;
  struct Demo d2;
  int i = 0;
  for(i=0; i<10; i++)
  {
    d1.p[i] = 0; // OOPS!  对为初始化的指针赋值
  }
  d2.p = (int*)calloc(5, sizeof(int));
  for(i=0; i<10; i++)
  {
    d2.p[i] = i; // OOPS!  数组越界,非法操作
  }
  free(d2.p);
  return 0;
}

•内存分配成功,但并未初始化

int main()
{
  char* s = (char*)malloc(10);  //并未初始化   内存申请成功后一定要初始化

  printf(s); // OOPS!  C语言字符串还是字符数组区别在于结尾有没有\0  结束符  这里printf打印长度不一定 ,内容无法预估

  free(s);
  return 0;
}

•数组越界

void f(int a[10])
{
  int i = 0;
  for(i=0; i<10; i++)
  {
    a[i] = i; // OOPS!
    printf("%d\n", a[i]);
  }
}

int main()
{
  int a[5];
  f(a);    //数组在作为函数形参时退化为指针   数组越界操作
  return 0;
}

•内存泄漏错误

void f(unsigned int size)
{
  int* p = (int*)malloc(size*sizeof(int));
  int i = 0;
  if( size % 2 != 0 )
  {
    return; // OOPS!  返回造成申请的空间没有释放   设计函数时最好是单入口,单出口。这个程序单入口,双出口。
  }
  for(i=0; i<size; i++)
  {
    p[i] = i;
    printf("%d\n", p[i]);
  }
  free(p);
}

int main()
{
  f(9);
  f(10);
  return 0;
}

•多次释放指针

void f(int* p, int size)
{
  int i = 0;
  for(i=0; i<size; i++)
  {
    p[i] = i;
    printf("%d\n", p[i]);
  }
  free(p);
}

int main()
{
  int* p = (int*)malloc(5 * sizeof(int));
  f(p, 5);
  free(p); // OOPS!   谁申请谁释放,不要重复释放内存 ,不要在main中申请的f中释放。  多次释放指针会造成程序异常退出。

  return 0;
}

•使用已经释放的内存

void f(int* p, int size)
{
  int i = 0;
  for(i=0; i<size; i++)
  {
    printf("%d\n", p[i]);
  }
  free(p);//p会变为一个野指针
}

int main()
{
  int* p = (int*)malloc(5 * sizeof(int));
  int i = 0;
  f(p, 5);
  for(i=0; i<5; i++)
  {
    p[i] = i; // OOPS!  一直在操作一个野指针   影响可重可轻
  }
  return 0;
}

posted @ 2020-08-06 18:01  起的比鸡还早  阅读(362)  评论(0)    收藏  举报