目录
判断当前机器的字节序(大小端)
#include <stdio.h>
//方法1
//int check_sys()
//{
// int a = 1;
// return *(char*)&a;
//}
//方法2
int check_sys()
{
union
{
int i;
char c;
}nu;
nu.i = 1;
return nu.c;
}
int main()
{
int ret = check_sys();
if (1 == ret)
printf("小端");
else
printf("大端");
return 0;
}
动态内存开辟常见错误
//错误1:对NULL指针的解引用操作
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(10000000000000);
//此处应判断p是否等于NULL,因为malloc返回值可能是NULL
//因此*(p + 1)可能对NULL解引用
for (int i = 0; i < 10; i++)
{
*(p + 1) = i;
printf("%d ", *(p + 1));
}
free(p);
p = NULL;
return 0;
}
//错误2:动态开辟空间的越界访问
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
return 1;
for (int i = 0; i < 40; i++) //越界访问
{
*(p + 1) = i;
printf("%d ", *(p + 1));
}
free(p);
p = NULL;
return 0;
}
//错误3:使用free释放非动态开辟的空间
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[10] = { 0 }; //栈区
int* p = a;
free(p); //使用free释放非动态开辟(堆区)的空间
p = NULL;
return 0;
}
//错误4:使用free释放一块动态开辟内存的一部分
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
return 1;
for (int i = 0; i < 9; i++)
{
*p++ = i;
}
//*p++改变了p的值(不再指向空间起始位置),存在两个问题:
//一是free只释放了一部分(p之后的),二是这段内存之后可能无法访问
free(p);
p = NULL;
return 0;
}
//错误5:对同一块动态内存多次释放
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
return 1;
//使用
//释放
free(p);
//释放
free(p);
return 0;
}
//上述情况系统报错,但每次free之后将p置为NULL就不会报错
int main()
{
int *p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
return 1;
//使用
//释放
free(p);
p = NULL;
//释放
free(p);
p = NULL;
return 0;
}
//错误6:动态开辟内存忘记释放(内存泄漏)
#include <stdio.h>
#include <stdlib.h>
void test()
{
int *p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
return 1;
//使用
}
int main()
{
test();
//.....
return 0;
}
//p指向动态内存空间,p是局部变量,在函数结束时自动销毁,
//如果函数内没有free释放空间,p销毁后将无法再找到这个动态内存空间。
//-----造成内存泄漏
练习题
//下面程序有哪些问题?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void test(char* pc)
{
pc = (char*)malloc(100);
}
int main()
{
char* p = NULL;
test(p);
strcpy(p, "hello");
printf(p);
return 0;
}
//p传给test函数的时候是值传递,所以当test函数返回之后,p依然是NULL。所以strcpy会失败。
//当test函数返回之后,形参pc销毁,使得动态开辟的100个字节存在内存泄漏。无法释放。
//正确写法:
//1。二级指针传参
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void test(char** pc)
{
*pc = (char*)malloc(100);
}
int main()
{
char* p = NULL;
test(&p);
strcpy(p, "hello");
printf(p);
free(p);
p = NULL;
return 0;
}
//2.使用return返回动态空间地址
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* test(char* pc)
{
pc = (char*)malloc(100);
return pc;
}
int main()
{
char* p = NULL;
p = test(p);
strcpy(p, "hello");
printf(p);
free(p);
p = NULL;
return 0;
}
//注意:上述代码均未对malloc返回值做判断
//下面程序有哪些问题?
#include <stdio.h>
char* test(void)
{
char p[] = "hello";
return p;
}
int main()
{
char* str = NULL;
str = test();
printf(str);
return 0;
}
//动态开辟内存在堆区,函数结束内存空间还在,返回地址有意义
//但是,栈区的内存在函数结束后会还给操作系统,返回地址没有意义
//下面代码有什么问题?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* test(void)
{
char* str = (char*)malloc(100);
strcpy(str, "hello");
free(str);
//free已释放空间但未将str置为NULL,导致下面代码非法访问内存
if (str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
int main()
{
test();
return 0;
}