学习小总结
这两天看了《Linux C编程实战》中的部分内容,主要有以下几个方面:
一、gdb 调试器
大部分初学者都对gdb调试这块很模糊,我个人认为简单的gdb调试对我来说是没有问题的。作为一个菜鸟,通过学习,我觉得这方面有了很大的提高。
首先,gdb 调试是针对那些肉眼无法看到的错误所采用的方法,主要有结果错误或者出现段错误的问题而言的。
gdb 调试的一般步骤为:
Linux@linux:~$ gcc 1.c -o 1 -g
Linux@linux:~$ gdb 1
如果成功进入调试阶段,就进行下面的步骤:
(gdb)list //显示源代码,每次10行
(gdn)break //断点的设置
(gdb)run //程序从断点处开始run
(gdb)next //让程序继续跑下去
(gdb)step // 可以展开被调函数,让其分步执行
(gdb)q // 退出调试阶段
上面这些就是gdb 调试的具体过程,其中next和 step可以交替使用,如果想看程序在被调函数中是如何执行的,建议使用step。
二、程序中的常见错误及经典例题
1.这是一道数组和指针相结合的例题,很经典哦~
#include <stdio.h>
void main()
{
int a[5] = {1, 2, 3, 4, 5};
int *ptr = (int *)(&a + 1);
printf("%d, %d\n",*(a + 1), *(ptr -1))
}
输出结果是:2,5 2很好理解,*(a + 1) <=>a[1],其中的5实际上就是由a[4]得来的,( &a )指指针偏移了一个数组的大小,因此 (&a + 1) <=> &a[5],这样*(ptr - 1)的结果是5就不难理解了。
2.这是一道改错题,很具有启发姓哦~
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char a;
char *str = &a;
strcpy (str, "hello");
printf("%s\n",str);
return 0
}
这个程序看起来很完美,但实际运行时却出现了大的错误,编译是可以通过的,但是程序会崩溃。正是由于str所指向的变量只占1个字节,而hello要占6个字节,所以需要更大的内存空间。聪明的你应该想到解决的方法了吧?
其实很简单,就是在使用str之前先申请内存空间,即 str =(char *)malloc(strlen ("hello") + 1);用完之后记得要释放内存哦,即free(str);嗯~ok!
三、关于内存对齐的问题(Linux下64位机)
1.按8字节对齐
(1)
union data1
{
double d;
int i;
char c1;
char c2[9];
};
sizeof(union data1) = 16,由于double是8个字节而 char c2[9]占9个字节,所以为了内存对齐,union data1就占16个字节。
(2)
struct data1
{
double d;
int i;
char c1;
char c2[9];
};
sizeof(struct data
1) = 24,
本应该是8 + 4 + 1 + 9 = 22,因为22不是8的倍数,为了内存对齐,所以应该是24而不是22.
2、按4字节对齐
(1)
union data2
{
int i;
char c1;
char c2[9];
};
sizeof(union data
2)
= 12,由于int 是4个字节,所以union data2的大小一定是4的倍数,char c2[9] 所占的字节数是9,所以整个union data2所占的字节数是12.
(2)
struct data2
{
int i;
char c1;
char c2[9];
};
sizeof(struct data2) = 16,
由于4 + 1 + 9 = 14不是4的倍数,内存对齐所以答案应该是16.
3、交换顺序后的各种奇葩~~~
(1)
struct inner
{
char c1;
double d;
char c2;
};
sizeof(struct inner) = 24; 内存的补齐原理,系统会给char c1分配8个字节的内存,同理char c2也一样,种种所有使得答案为24.
(2)
struct inner
{
double d;
char c1;
char c2;
};
si
zeof(struct inner) = 16; char c1和char c2各分配1个字节,其余6个字节的内存空闲,系统就轻而易举的给struct inner 分配了16个字节的内存。
4、复杂的嵌套问题,感觉不容易理解~~
(1)
struct inner
{
char c1;
double d;
char c2;
};
union data4
{
struct inner t1;
int i;
char c;
};
sizeof(union data4) = 24; 因为其中的sizeof(struct inner) =24,所以很容易理解到答案应该是24.
(2)
struct inner
{
char c1;
double d;
char c2;
};
struct data4
{
struct inner t1;
int i;
char c;
};
sizeof(struct data
4) = 3
2;
在整个结构体和共用体中,占内存最大的当然是double 了,所以是以8个字节为对齐标准,24 + 4 +1 = 29不是8的倍数,所以结果应该是32.
通过这两天的学习掌握了好多东西,这篇博客中可能会有很多不足,以后慢慢改进,加油!