作者:张裕鹏 日期:2021-5-11
1. 内存对齐导致的错误
内存对齐在 C 语言基础考试的时候经常会考到,其实很多人只是知道这个概念,但是并不清楚在实际中会有什么应用,下面给一个例子来进行说明。
常见的内存对齐一般出现在结构体中,如下
typedef struct C2C_AV_TRANS_FIXED_HEADER_{
unsigned int request_id;
unsigned long long int time_ms;
int extension_length;
}C2C_AV_TRANS_FIXED_HEADER;
该结构体的大小为:24 Byte 。如果这个都不理解,可以看看这篇文档:如何理解 struct 的内存对齐?
上面的结构体是一个媒体文件头,那在通过网络传输过来之后(都是 char 类型),想知道 extension_length 的内容是多少,该如何获取呢?可以看看下面代码
int main()
{
C2C_AV_TRANS_FIXED_HEADER c;
c.request_id = 123;
c.time_ms = 456;
c.extension_length = 789;
char *buf = (char *)malloc(100);
if(buf == NULL){
printf("malloc failed !\n");
return -1;
}
memcpy(buf, &c, sizeof(C2C_AV_TRANS_FIXED_HEADER));
int length = *(int*)(buf+16);
printf("length:%d\n", length);
return 0;
}
结果如下:length:789
这边要特别注意代码:int length = *(int*)(buf+16)
- 这边将 buf 内容先偏移 16 字节(因为 buf 的类型为 char * 类型,所以可以直接 +16);
- 然后再将类型转换为(int *);
- 最后再解引用;
这块内容经常会写错,比如写成:int length = (int)*(buf+16)
,需要特别注意!
2. 强制类型转换导致的错误
对于强制类型转换如果理解不足,经常会导致莫名的错误,下面介绍一种由于强制类型转换导致的程序崩溃。
void change(int *num)
{
*num = 256;
}
int main()
{
short a = 0;
change(&a);
printf("a: %d\n", a);
return 0;
}
上面的程序会导致程序崩溃,主要的原因是 short 只有 2 个字节,而 int 有 4 个字节,所以将 a 的地址传入之后,chang 函数会将该指针认为是 int * 类型,导致使用的时候使用了 4 个字节,造成了栈溢出,导致了崩溃。
所以在写代码的时候一定要避免类似这样的错误,因为有时候这个看起来不明显。