#include
#include
int main()
{
int* p1 = (int*)malloc(40);
int* p2 = (int*)1234567; //整形强制转换成指针,为野指针
int i = 0;
for(i=0; i<40; i++)
{
*(p1 + i) = 40 - i; //申请了40字节内存,这里访问越界了
}
free(p1);
for(i=0; i<40; i++)
{
p1[i] = p2[i]; //使用已经释放了的指针p1
}
return 0;
}
#include
#include
#include
struct Student
{
char* name;
int number;
};
char* func()
{
char p[] = "D.T.Software";
return p;
}
void del(char* p)
{
printf("%s\n", p);
free(p);
}
int main()
{
struct Student s; //成员char* name没有初始化
char* p = func(); //传递了局部数组的指针
strcpy(s.name, p);
s.number = 99;
p = (char*)malloc(5);
strcpy(p, "D.T.Software"); //p的内存不够,访问越界
del(p);
return 0;
}
修改后:
#include
#include
#include
struct Student
{
char* name;
int number;
};
char* func()
{
static char p[] = "D.T.Software"; //返回静态局部指针变量,程序调用结束,内存不释放
return p;
}
void del(char* p)
{
printf("%s\n", p);
free(p);
}
int main()
{
struct Student s;
s.name=NULL;
char* p = func();
s.name=(char*)malloc(strlen(p)+1); //申请足够大的内存
strcpy(s.name, p);
printf("s.name=%s\n",s.name);
s.number = 99;
p=NULL;
p = (char*)malloc(13); //申请足够大的内存
printf("p=%p\n",p);
strcpy(p, "D.T.Software");
printf("strlen(p)=%d\n", strlen(p));
printf("p=%p\n",p);
del(p);
return 0;
}
示例:
#include
#include
void test(int* p, int size)
{
int i = 0;
for(i=0; i<size; i++)
{
printf("%d\n", p[i]);
}
free(p);
}
void func(unsigned int size)
{
int* p = (int*)malloc(size * sizeof(int));
int i = 0;
if( size % 2 != 0 )
{
return;
}
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));
test(p, 5);
free(p); //多次释放,其次释放后,指针没有赋为NULL,为野指针
func(9); //函数内申请的指针未被释放
func(10);
return 0;
}
#include
#include
struct Demo
{
char* p;
};
int main()
{
struct Demo d1;
struct Demo d2;
char i = 0;
for(i='a'; i<'z'; i++)
{
d1.p[i] = 0; //d1.p并未申请内存,并且下表太大'a'==48
}
d2.p = (char*)calloc(5, sizeof(char)); //申请内存并且初始化为0,calloc会将内存初始化为0
printf("%s\n", d2.p);
for(i='a'; i<'z'; i++)
{
d2.p[i] = i; //下标访问越界
}
free(d2.p); //释放后,没有指向NULL,为野指针
return 0;
}
int *p =(int *)malloc(56);
if(p!=NULL)
{
//Do something here!
}
free(p);
int *p =(int *)malloc(20);
free(p);
p=NULL;
void print(int *p,int size)
{
int i=0;
char buf[128]={
0};
snprintf(buf,sizeof(buf),"%s","rengeshuai");
for(int i=0;i<size;i++)
{
printf("%d\n",p[i]);
}
}
void func()
{
int *p=(int *)malloc(sizeof(int)*4);
free(p);
}
int main()
{
int *p=(int *)malloc(40);
func();
free(p);
return 0;
}
tips
严格意义上的声明和定义并不相同
举例:
//global.c
#include
int g_var = 10;
struct Test
{
int x;
int y;
};
void f(int i, int j)
{
printf("sizeof(struct Test)=%d\n",sizeof(struct Test));
printf("i + j = %d\n", i + j);
}
int g(int x)
{
return (int)(2 * x + g_var);
}
//test.c
#include
#include
extern int g_var;
extern struct Test;
int main()
{
extern void f(int i, int j);
extern int g(int x);
//struct Test* p = NULL;
struct Test* p =(struct Test*)malloc(sizeof(struct Test));
//printf("sizeof(struct Test)=%d\n",sizeof(struct Test));
//printf("p = %p\n", p);
//g_var = 10;
printf("g_var = %d\n", g_var);
f(1, 2);
printf("g(3) = %d\n", g(3));
//free(p);
return 0;
}
在这里根本找不到结构体Test 的定义,定义和声明是不一样的
示例:
#include
int func(int i, int j)
{
printf("%d, %d\n", i, j);
return 0;
}
int main()
{
int k = 1;
func(k++, k++);
printf("%d\n", k);
return 0;
}
函数参数的计算次序是依赖编译器实现的,那么函数参数的入栈次序是如何确定的呢?
示例:1.普通函数求平均 2.可变参数求int 类型的平均值
#include
#include
float average_arg(int n,...)
{
va_list args;
float sum=0;
va_start(args,n);
for(int i=0;i<n;i++)
{
sum+=va_arg(args,int);
}
va_end(args);
return sum/n;
}
float average(int array[], int size)
{
int i = 0;
float avr = 0;
for(i=0; i<size; i++)
{
avr += array[i];
}
return avr / size;
}
int main()
{
int result=average_arg(3,1,2,3);
int result_1=average_arg(5,1,2,3,4,5);
printf("result=%d\n",result);
printf("result_1=%d\n",result_1);
return 0;
}
注意:
va_arg中如果指定了错误的类型,那么结果是不可预测的。
示例:
#include
#define RESET(p, len) \
while( len > 0 ) \
((char*)p)[--len] = 0
void reset(void* p, int len)
{
while( len > 0 )
((char*)p)[--len] = 0;
}
int main()
{
int array[] = {
1, 2, 3, 4, 5};
int len = sizeof(array);
int i = 0;
for(i=0; i<5; i++)
{
printf("array[%d] = %d\n", i, array[i]);
}
return 0;
}
#include
#define _ADD_(a, b) a + b
#define _MUL_(a, b) a * b
#define _MIN_(a, b) ((a) < (b) ? (a) : (b))
int main()
{
int i = 1;
int j = 10;
printf("%d\n", _MUL_(_ADD_(1, 2), _ADD_(3, 4)));
printf("%d\n", _MIN_(i++, j));
return 0;
}
预编译后的结果:(宏定义就是文本替换)
int main()
{
int i = 1;
int j = 10;
printf("%d\n", 1 + 2 * 3 + 4);
printf("%d\n", ((i++) < (j) ? (i++) : (j)));
return 0;
}
#include
#include
#define MALLOC(type, x) (type*)malloc(sizeof(type)*x)
#define FREE(p) (free(p), p=NULL)
#define LOG_INT(i) printf("%s = %d\n", #i, i)
#define LOG_CHAR(c) printf("%s = %c\n", #c, c)
#define LOG_FLOAT(f) printf("%s = %f\n", #f, f)
#define LOG_POINTER(p) printf("%s = %p\n", #p, p)
#define LOG_STRING(s) printf("%s = %s\n", #s, s)
#define FOREACH(i, n) while(1) { int i = 0, l = n; for(i=0; i < l; i++)
#define BEGIN {
#define END } break; }
int main()
{
int* pi = MALLOC(int, 5);
char* str = "D.T.Software";
LOG_STRING(str);
LOG_POINTER(pi);
FOREACH(k, 5)
BEGIN
pi[k] = k + 1;
END
FOREACH(n, 5)
BEGIN
int value = pi[n];
LOG_INT(value);
END
FREE(pi);
LOG_POINTER(pi);
return 0;
}
tips:
递归将大型复杂问题转化为与原问题相同但规模较小的问题进行处理
示例:
#include
int strlen_r(const char* s)
{
if( *s )
{
return 1 + strlen_r(s+1);
}
else
{
return 0;
}
}
int main()
{
printf("%d\n", strlen_r("abc"));
printf("%d\n", strlen_r(""));
return 0;
}
#include
int fac(int n)
{
if( n == 1 )
{
return 1;
}
else if( n == 2 )
{
return 1;
}
else
{
return fac(n-1) + fac(n-2);
}
return -1;
}
int main()
{
printf("%d\n", fac(1));
printf("%d\n", fac(2));
printf("%d\n", fac(9));
return 0;
}
#include
void han_move(int n, char a, char b, char c)
{
if( n == 1 )
{
printf("%c --> %c\n", a, c);
}
else
{
han_move(n-1, a, c, b);
han_move(1, a, b, c);
han_move(n-1, b, a, c);
}
}
int main()
{
han_move(3, 'A', 'B', 'C');
return 0;
}
void sc(char*s1,char*s2);
void str_copy(char* str_dest,char *str_src);
void str_copy(char *str_dest,const char * str_src);
char s[64];
int len=strlen(strcpy(s,"android"));
char c=getchar(); // 实际上getchar()返回的是int类型,字符的ascill值
if(EOF==c)
{
}