C指针(8):安全和误用

安全和误用

1.声明和初始化

//1.错误的声明
int* ptr1,ptr2;

//正确声明
int *ptr1,*ptr2
//OR
#define PINT int*
PINT ptr1,ptr2;
//OR
typedef int* PINT;
PINT ptr1,ptr2;

//2.处理未初始化的指针
//NULL
int* ptr = NULL;
//assert函数,指针为空程序中止
assert(ptr != NULL)

2.缓冲区溢出

//1.malloc一定要检查返回值
float *vector = malloc(20 * sizeof(float));
if(vector == NULL) {
    // malloc分配内存失败
} else { 
    // 处理vector 
}

//2.谨慎使用strcpy,strcat,gets等允许缓冲区溢出的函数

//3.有界指针
#define SIZE 32
char name[SIZE];
char *p = name;
if(name != NULL) { 
    if(p >= name && p < name+SIZE) { 
        // 有效指针,继续 
    } else { 
        // 无效指针,错误分支
    }
}

//4.结构体
//结构体的内存分配不一定是连续的,使用指针算术符可能出现错误

//错误的使用
Employee employee;
// 初始化employee
char *ptr = employee.name;
ptr += sizeof(employee.name);

//正确的使用
Item part = {12345, 35, 107};
int *pi = &part.partNumber;
printf("Part number: %d\n",*pi);
pi++;
printf("Quantity: %d\n",*pi);
pi++;
printf("Bin number: %d\n",*pi)
//OR
int *pi = &part.partNumber;
printf("Part number: %d\n",*pi);
pi = &part.quantity;
printf("Quantity: %d\n",*pi);
pi = &part.binNumber;
printf("Bin number: %d\n",*pi)
//OR
printf("Part number: %d\n",part.partNumber);
printf("Quantity: %d\n",part.quantity);
printf("Bin number: %d\n",part.binNumber);

//5.函数指针
//只用函数名本身时返回的是函数的地址

3.内存释放

//1.重复释放:将同一块内存释放两次称为重复释放
//简单办法是释放指针后总是将其置为NULL,大部分堆管理器都会忽略后续对空指针的释放

//2.清除内存中敏感数据
char *name = (char*)malloc(...);
...
memset(name,0,sizeof(name));
free(name);

你可能感兴趣的:(C指针(8):安全和误用)