最近在写程序时遇到了一些问题,记录一下:
开始程序使用全局变量,程序如下:程序的缺点是全局变量的泛滥。
笔者觉得有些不妥,于是将它修改成这样:
使用结构体进行封装,避免了全局变量,后续还可以使用设计模式,移植和可读性都会变得更加容易,为了修改变量的值,采用的方式是传址调用。如果采用传值调用,函数会将实参的值复制给形参,因此,函数内部对形参的修改不会影响到实参的值,这显然是不行的。
在传址调用的基础上,笔者又进行修改,将token变量改为指针。
程序如下:
刚开始,笔者并没有初始化token指针,直到编译程序并执行后,程序出现segmentation fault,使用gdb调试时,意识到没有初始化内存,于是使用malloc函数分配,执行完程序后再使用free释放。
现在就来到重点了,为什么我使用int token不需要malloc,而使用int *token就需要手动allocated呢?
首先,int token,代表token的大小是已知的,就是一个int,但是int *token,token只是代表一个指向int的一个指针,是需要我们初始化的,不然直接*token的后果就是野指针,你也不知道它到底指向了哪里。
那么问题又来了,既然是指针解引用问题,为什么malloc后,指针就能被正确初始化?
内存中,有stack,也有heap,stack用于生命周期短的变量,heap用于生命周期长的变量。
使用malloc时,是在heap中开辟一片空间。但其实一个变量在stack还是heap,跟它是静态还是动态也有关系。
当使用int token时,编译时complier就已经知道了token的大小,所以它被分配到了stack中的一片空间,这就是静态。
当使用int *token时,它的大小我们无法确定,必须由我们手动分配并且释放,否则就会造成内存溢出。考虑到它的动态性质,只有程序运行时我们才能得知它的大小,编译器无法直接得出,所以我们需要使用malloc函数进行内存分配,此时,token相当于有了一个范围,解引用时不会出现野指针现象。