1. 函数参数为一级指针,函数内部参数的指针改变并不影响原来传入指针本身的值。
void ptr_mdy(void *ptr) { ptr = malloc(100); assert(ptr); printf("In the func: %x\n", (unsigned int)ptr); } int main() { void * ptr = malloc(100); assert(ptr); printf("Former: %x\n", (unsigned int)ptr); ptr_mdy(ptr); printf("Out of func: %x\n", (unsigned int)ptr); return 0; }ptr的值未被改变。
如果要修改ptr的值,那么要用二级指针, 修改如下
void ptr_mdy(void **ptr) { *ptr = malloc(100); assert(*ptr); printf("In the func: %x\n", (unsigned int)*ptr); } int main() { void * ptr = malloc(100); assert(ptr); printf("Former: %x\n", (unsigned int)ptr); ptr_mdy(&ptr); printf("Out of func: %x\n", (unsigned int)ptr); return 0; }
2. 函数返回局部变量数组,局部结构体指针(非malloc分配的)错误。因为函数返回,栈上内容被回收。
int *ptr_ret() { int ptr[100] = {0}; return ptr; } int main() { int * ptr = ptr_ret(); return 0; }函数返回后,ptr成为野指针。
3. 如果两个结构体相互包含,至少一方为指针,然后把指针对象的结构体声明放在前面,具体声明放到后面。不能两个相互包含的结构体都是普通变量类型(就是非指针类型)。即:
struct b; struct a{ struct b * test; }; struct b{ struct a test; };
struct a{ struct a test; };
6. 指针类型的内容不能直接赋值,要通过内存拷贝的方式。比如字符串,结构体。
7. 对于strlen、strcmp等函数需要检查参数是否为NULL,否则容易一不小心而挂掉,因为内部需要访问参数地址的内容, 使用strnlen, strncmp会更加安全,防止没有字符串结束符。
8. sizeof是c 编译器的一个关键字,用于静态检测分配的内存。
9. char **argv != char copy[a][b]; 不可以直接赋值,因为argv[]是指向字符串的指针,而copy[]是指向间距为b的空间,内存布局不一样。常见错误
int callback(char **argv, int argc) { int i; for (i = 0; i < argc; i++) printf("argv[%d]: %s\n", i, argv[i]); } int main() { char copy [100][10]; memcpy(copy[1], "1", 1); memcpy(copy[2], "2", 1); memcpy(copy[3], "3", 1); callback(©[2], 2); return 0; }把char *argv[] 改为 char argv[][10] 即可。
10. 数据类型转换。
比如
int i = 16384.
char j = i;
这时,因为16384 = 0x4000, 所以 j = 0;这就可能导致整个系统逻辑不对了。
11. int data;
int data = 10;
printf("%s\n", data);
这样就挂了