cs61c-lab02
Lab 2: Advanced C
cs61c - Great Ideas in Computer Architecture (Machine Structures) lab 笔记第二篇
Exercise 0: Makefiles
makefile教程:https://seisman.github.io/how-to-write-makefile/introduction.html
Exercise 1: Bit Operations
完成get_bit
, set_bit
, and flip_bit
独立完成后,查看别人的实现学习到了更简洁更直观的表达,就理下别人的思路
1 |
|
(x >> n)
:首先,将整数x
向右移动n
位,以便将第n
位移到最低位,这样我们可以轻松地从最低位提取出这个位的值。(1 & (x >> n))
:然后,将移位后的结果与二进制数0b00000001
(即1)进行按位与操作。这将保留右移后的结果的最低位,也就是第n
位。return (1 & (x >> n));
:最后,将上述按位与操作的结果作为函数的返回值,即返回第n
位的值(0 或 1)。
1 |
|
unsigned mask = ~(1<<n);
:首先,创建一个掩码mask
,它的目的是将第n
位设置为0,其他位都保持不变。这是通过将数字1左移n
位然后取反得到的,实际上就是将第n
位设置为0,其他位都设置为1。(*x) = ((*x) & mask)|(v << n);
:然后,使用掩码和左移操作将指定的位设置为新的值v
。(*x) & mask
:这个步骤将保留x
中除第n
位以外的所有位,通过将x
和掩码mask
进行按位与操作。v << n
:将值v
左移n
位,将要设置的位放置在正确的位置。((*x) & mask) | (v << n)
:将上述两个步骤的结果进行按位或操作,将保留的部分与设置的位合并,得到最终的结果。
1 |
|
(1 << n)
:首先,将数字1左移n
位,生成一个只有第n
位为1,其他位为0的数。例如,如果n
是3,则1 << 3
的结果是二进制数0b00001000
。(*x) ^= (1 << n);
:然后,将左移后的结果与原始值x
进行按位异或操作(^=
表示按位异或赋值操作)。按位异或操作的性质是,对于两个操作数的每一位,如果两个操作数的对应位不同,则结果的该位为1,否则为0。因此,这个操作将会翻转x
的第n
位。
Exercise 2: Linear Feedback Shift Register
很简单的一个东西,由于makefile 设置的原因,不要调用bit_ops.c
的函数在lfsr.c
中
lfsr倒是蛮有意思
Exercise 3: Memory Management
最开始没想明白两个函数为什么有问题,只是觉得跟之前写的不一样,因为之前结构也要malloc分配空间。
贴上chatgpt的解释
bad_vector_new()
1 |
|
它试图返回一个指向局部变量的指针,这会导致悬空指针问题,而且在修改局部变量的成员时也会导致未定义行为。
具体来说,这段代码的问题在于:
vector_t v;
:在堆栈上创建了一个局部变量v
,它的生命周期仅限于bad_vector_new()
函数的执行期间。retval = &v;
:将局部变量v
的地址赋给了retval
,使得retval
指向了局部变量v
所在的内存地址。retval->size = 1;
和retval->data = malloc(sizeof(int));
:试图在局部变量v
上操作,但由于它是在堆栈上分配的,这会导致未定义行为。这意味着你正在修改一个局部变量的成员,而不是动态分配的内存。return retval;
:返回了指向局部变量v
的指针retval
。
这会导致类似前面提到的问题,当函数 bad_vector_new()
结束时,局部变量 v
将被销毁,但是 retval
仍然指向了该内存地址,从而导致悬空指针。同时,试图在局部变量上进行成员访问也会导致未定义行为。
also_bad_vector_new()
1 |
|
它试图返回一个局部变量 v
,它在函数结束时将会被销毁,导致悬空指针问题。
具体问题如下:
vector_t v;
:在堆栈上创建了一个局部变量v
,它的生命周期仅限于also_bad_vector_new()
函数的执行期间。v.size = 1;
和v.data = malloc(sizeof(int));
:在局部变量v
上操作,分配了内存并将指针存储在v.data
中。由于v
是在堆栈上分配的,当函数also_bad_vector_new()
结束时,局部变量v
将被销毁,导致v.data
指向的内存变成了悬空指针。return v;
:试图返回局部变量v
。
这会导致悬空指针问题,因为在函数结束后,局部变量 v
将被销毁,但是返回的 v
中的指针 v.data
仍然指向了之前分配的内存地址
综上,就是malloc这个应该在heap上调用的函数,不应用到stack上,导致的一系列问题
vector_new()
1 |
|
正常思路,给struct 手动分配内存就好
vector_set()
1 |
|
注意设0时,别覆盖了之前设置过值就好
makefile test
结果:
1 |
|
注意:
- 在 makefile 中为
vector-test
目标实施规则。 - 在 vector.h 中添加函数声明
cs61c-lab02
https://2333monster.github.io/2023/08/10/cs61c-lab02/