Leetcode 第一刷纪念笔记

一直觉得C语言学得还不错,且早已听说Leetcode的大名,今天悻悻地去leetcode的官网刷了第一道题 —- Circular Queue

做完后暴露了好多问题。

其题目要求如下(点击图片放大):

系统隐藏了main函数的部分,只给出了要求使用和补充完善的函数(点击图片放大):

乍一看,一脸懵逼。我结构题哪里定义?这也没给我传进第一个初始化函数啊?

不得不说,这里让我纠结了许久,脑子转不过来,后来突然想到,根据最后的注释提示,应该是初始化函数 myCircularQueueCreate(int k) 这里,申请了一个内存空间时创建了结构体,然后函数返回时并不会清理掉这部分内存,当初写C语言终端离线词典时自己就是这么干的,只要把这部分内存首地址返回给调用函数就可以了。

另外,不能在函数中不申请内存直接初始化一个结构体,再返回结构体的地址。如果这样的话,函数返回时这些数据都会被释放掉,返回的地址也就没用了,如果这个时候再操作这个地址指向的内存空间,将会发生Segmentation fault。

还有一个问题需要注意,如果申请了一段内存空间,并且访问了该内存空间之外的地址(如申请内存中的数组越界),当下可能不会报错,为什么说是可能呢?因为一般这种情况下指针跑飞到的地方,访问的都是不影响系统运行的位置,如果不幸撞到了枪口,那就只能立即‘挂机’了。

接着上面的,当下虽然没有报错宕机,但是当调用free函数释放该段内存时,程序就会抛出double free or corruption (out)的错误了。

为什么会这样呢?因为当我们申请内存空间时,实际用到的内存会比我们申请的大一点,这个额外的空间就是用来记录这部分的长度以及下一个分配块的地址等等的,如果发生了越界,就会改写到这部分信息,最终调用free时会检测到异常而抛出错误。

至于这部分额外空间在哪呢,在我的电脑上检测后,发现,应该在内存前后都有一些关键信息,无论是向前还是向后越界,free都会发生错误,只不过报错信息不同,说明其前后存的信息是不同的(废话了,相同还存什么,手动捂脸。另:这部分的具体原因,等我查阅好相关文档后再来填坑。)

这题虽然不难,自己思路也很清晰,但问题就在于手跟不上大脑,打出来的跟想的还不一样,细节上被自己坑了很多次,以为想的是对的,打出来后就一样了,一眼扫过也没发现有些代码顺序在修改的时候已经不小心调换了,这就造成了代码上致命的逻辑错误了。

最后奉上代码被Accepted的截图吧(点击图片放大):