如下代码执行结果是什么?
objectivec
#include <stdio.h>
#include <string.h>
struct test_info {
int a;
char *name;
};
static struct test_info hhh_info[2];
static char test_name[2][8];
int main()
{
for (int i = 0; i < 2; i++) {
memset(&hhh_info[i], 0, sizeof(hhh_info));
snprintf(test_name[i], sizeof(test_name[i]), "good%d", i);
hhh_info[i].name = test_name[i];
}
for (int j = 0; j < 2; j++) {
printf("hhh_info name: %s\n", hhh_info[j].name);
printf("test_name[j] is: %s\n", test_name[j]);
}
printf("test_name addr is: %p\n", test_name);
printf("hhh_info addr is: %p\n", hhh_info);
return 0;
}
gcc编译后执行结果如下:
bash
hhh_info name:
test_name[j] is:
hhh_info name: good1
test_name[j] is: good1
test_name addr is: 0x564026243060
hhh_info addr is: 0x564026243040
会发现hhh_info第一个元素为空,奇怪?分析下看下
首先代码bug是由于memset误将整个数组的大小传入,导致第二次循环越界。
objectivec
memset(&hhh_info[i], 0, sizeof(struct test_info));
但是为什么会导致第一个元素为空呢?从打印的地址可以看到,test_name和hhh_info相差32字节。struct test_info大小为16字节,hhh_info大小为32字节,所以test_name在内存布局上紧挨着hhh_info,因此,第二次循环时,会将整个test_name空间情况,2x8正好为16字节大小。
稍微调整下代码实现,看下输出结果:
objectivec
#include <stdio.h>
#include <string.h>
struct test_info {
int a;
char *name;
};
static char test_name[2][8];
static struct test_info hhh_info[2];
int main()
{
for (int i = 0; i < 2; i++) {
memset(&hhh_info[i], 0, sizeof(hhh_info));
snprintf(test_name[i], sizeof(test_name[i]), "good%d", i);
hhh_info[i].name = test_name[i];
}
for (int j = 0; j < 2; j++) {
printf("hhh_info name: %s\n", hhh_info[j].name);
printf("test_name[j] is: %s\n", test_name[j]);
}
printf("test_name addr is: %p\n", test_name);
printf("hhh_info addr is: %p\n", hhh_info);
return 0;
}
gcc编译后执行结果如下:
bash
hhh_info name: good0
test_name[j] is: good0
hhh_info name: good1
test_name[j] is: good1
test_name addr is: 0x5649a73c1040
hhh_info addr is: 0x5649a73c1060
低级编码bug可能会产生奇奇怪怪的问题。