首页 > 其他分享 >CS61c hw2 note

CS61c hw2 note

时间:2022-09-07 11:00:33浏览次数:70  
标签:char malloc pt int CS61c note 地址 str hw2


title: hw 2 note
date: 2022-09-07 周三
tags:

  • 位运算
  • c
  • Memory_Management
  • Pointer
  • Struct
  • union
  • endianness
    mindmap-plugin: basic

HW2.1、2.2

位运算,略

HW2.3. Memory Alpha Model

#define SPOCK 1701
int KIRK = 1701;
int sulu(int scotty) {
	return scotty * scotty;
}
int main(int argc, char *argv[]) {
	int *chekov = malloc(sizeof(int) * 1701);
	if (chekov) free(chekov);
	sulu(SPOCK); // ← snapshot just before it returns
	return 0;
}
名称 位置 类型
sulu code 函数
checkov stack 局部变量(malloc分配的指针)
*checkov heap malloc分配的指针指向的变量
KIRK static/data 静态变量(全局变量)
scotty stack 局部变量
SPOCK code 宏定义

Q1.1: sulu is a function, and therefore it is stored in the code.

Q1.2: The variable chekov itself is stored in the stack, since it's a local variable. Note that the value of chekov is a pointer elsewhere.

Q1.3: Since we set chekov to a pointer returned by malloc, *chekov is located on the heap.

Q1.4: KIRK is declared outside any function and is a variable, so it gets stored in the static/data segment.

Q1.5: scotty is a local variable (as a function argument) to the function sulu, so it gets stored on the stack. Note that the value of SPOCK gets copied into a new local variable,since C is pass-by-value.

Q1.6: SPOCK is a defined by a #define statement. Effectively, all instances of SPOCK get replaced with 1701 by the compiler before it continues to compile the code. As such, the value of SPOCK gets copied directly into the code

HW2.4. Memory Multiple Choice

1. Which parts of memory can fall under that category?

Data, Heap, and Stack generally contain segments of memory allocated by the user, but also contain buffers/metadata which help the system keep track of everything, and can contain data/heap/stack data of other processes.

所以在这些地方都有可能出现段错误。

2. What are general reasons such protections exist within a specific process?

From a debugging perspective, it is generally not correct behavior to access a memory location you didn't originally initialize.

As such, segfaults allow you to catch bugs more easily.

HW2.5. Memory Endianness

Let x be an 8-bit unsigned number. We consider the "first bit" to be the least significant bit, and the "eighth bit" to be the most significant bit.

1.

Suppose that we have the following bytes stored in memory:
0x00001000: 0x00
0x00001001: 0x01
0x00001002: 0xFF
0x00001003: 0xFF

big-endian = 0x0001FFFF = 131071

little-endian = 0xFFFF0100(补码) = 0x8000FF00(原码) = -65280

2.

uint32_t *x = malloc(sizeof(uint32_t)*4); //Assume that x == 0x20000000
x[0] = 0xDEADBEEF;
x[1] = 0xC561C156;
x[2] = 0x00DC1A55;
x[3] = 0xABADCAFE;
uint64_t y = *((uint64_t*)x);

Q2.1: The byte at address 0x2000000E is 0xAD (the 15th byte)
Q2.2: strlen goes to the first 0x00 byte, which is the 12th byte. Our string length is thus 11.
Q2.3: We interpret the first 8 bytes as a little-endian integer, so we get 0xC561C156DEADBEEF. Note that this is the same as x[1] and x[0] in order.

主要是理解下表以及little-endian

地址 (1)字节
0x20000000 0xEF
0x20000001 0xBE
0x20000002 0xAD
0x20000003 0xDE
0x20000004 0x56
0x20000005 0xC1
0x20000006 0x61
0x20000007 0xC5
0x20000008 0x55
0x20000009 0x1A
0x2000000A 0xDC
0x2000000B 0x00
0x2000000C 0xFE
0x2000000D 0xCA
0x2000000E 0xAD
0x2000000F 0xAB

HW2.6. Pointers

注意一点,数组名相当于一个指针,这个指针指向它自己,也就是说&x = x = 0x188c

An array variable is a “pointer” to the first (0-th) element.

K&R: “An array name is not a variable”

HW2.7 Pointers and Structs

1.

void changeX2 (Point *pt) {
	pt.x = 22;
}

Point my_pt;
changeX2(&my_pt);
printf("%d\n", my_pt.x);

Q1.3: The . operator to retrieve a field from a struct only works on a struct and not a struct pointer, so this code would not compile.

2.

void changeX5 (Point *pt) {
	pt = 55;
}
Point *my_pt = calloc(1, sizeof(Point));
changeX5(my_pt);
printf("%d\n", my_pt->x);

Q1.5: C is pass by value. This code passes the value of the pointer to changeX5 which mutates its local copy, and does nothing to change my_pt. Since the my_pt was calloc-ed, all of its fields were initialized to 0 and remain equal to 0

HW2.8. Strings

要充分理解'\0'在字符串中的意义,strlen()就是根据它来计算字符串长度的。

几种形式

char* a = "foobar";(不可修改)

char a[] = "foobar"

char a[] = {'f', 'o', 'o', 'b', 'a', 'r', '\0'};(可修改,与上面的相同,但要手动添加'\0')

char* a = "foo\0bar";(此时strlen(a) == 3)

HW2.9. Common C Pitfalls

1.

image-20220907091817214

申请空间过大,会失败,此时malloc不会报错,只会返回NULL。因此应该添加一段判断语句,if(x != NULL),才继续进行操作。

2.

int foo () {
	int *x = malloc(20);
	x[0] = x[1] = 1;
	x[2] = x[0] + x[1];
	x[3] = 99;
	return x[3];
}

free

3.

int main () {
	char *x = "patrick";
	printf("%s", x);
	free(x); // tidy up
}

不能free非malloc分配的区域

4.

void strncpy(char *destination, char *source, uint32_t maxlength)
{
    int i = 0;
    while (i < maxlength && source[i])
    {
        destination[i] = source[i];
        i++;
    }
    destination[strlen(destination)] = '\0';
}

最后一行会把最后一个字符(而不是'\0')赋值为'\0'

5.

#DEFINE MAXSTRINGLENGTH 64 // Assume that the string input is at most 64
characters long char *copystringtoheap(char *string)
{
    char *c = malloc(sizeof(char) * (MAXSTRINGLENGTH + 2));
    char *cclone = c;
    do
    {
        *(c++) = *string;
    } while (*(string++));
    free(c);
    return cclone;
}

只能free最开始malloc的那个指针

HW2.10. Reading Memory

str比较简单就略过了,主要是树

首先清楚这段代码的几个点

  • 树的右节点要么指向子树,要么是值
  • 树的左节点要么指向子树,要么为空
  • 叶子节点的左节点为空,右节点是值
  • printtree()的打印顺序从左到右叶子节点的值

q1

如图所示

image-20220907094458700

从左到右打印3 1 4 1 5 9 3

q2

这题推荐用vscode做,颜色比较丰富

首先解释以下下面这张图

image-20220907095005091

  • 每一行有四个单元,每个单元的大小是四个字节(4 bytes),每对十六进制数的大小是一个字节(1 byte = 8 bits)
  • 按行看,从左到右单元的地址是增大的;按单元看,从左到右单元的地址是减小的(little-endian)
  • 两行时间相差'10',这里的'10'是16进制的,相当于十进制的'16',与第一点是吻合的

接下来是地址

image-20220907100001960

由于是64位的机器,因此地址(指针)的大小是64位,也就是8字节,也就是两个单元,也可以说是8对(16个)十六进制数。

但是这里为什么长度只有12呢,因为前面几位都是0,所以省略了(可能有更丰富的原因)

0x7fffffffe350是a1的地址,该地址的值是0xef

类似的,下面用表格列出str的表示

地址 ascii(16) str[]
0x7fffffffe360 20 [space] str[0]
0x7fffffffe361 69 i str[1]
0x7fffffffe362 73 s str[2]
0x7fffffffe363 20 [space] str[3]
0x7fffffffe364 66 f str[4]
0x7fffffffe365 75 u str[5]
0x7fffffffe366 6e n str[6]
0x7fffffffe367 00 [null] str[7]

所以str = " is fun",注意最前面有一个空格

接下来是复原树

由上图知树的地址的地址0x7fffffffe358,也就是说树的地址存储在这里。从这里开始取8位就可以得到树的(根节点)地址0x00005555 557577f0(两个单元),这里就不再赘述。

找到这一行

image-20220907102035439

可以看到这一行有四个单元,回顾代码中树的定义,可以知道这里对应了两个地址left, right

顺便说一句,union的作用就是划定一段足够的空间,放置自定义的若干种数据的其中一种,在这里,指针需要两个单元,int需要1个单元格,所以这俩单元就是union规划的空间,足以容纳指针或者int。由于只有两种值,稍后我们可以很容易判断出来什么时候是指针,什么时候是值。

typedef struct tree {
  struct tree* left;
  union 
  {
    struct tree* right;
    int data;
  } rd;
} Inttree;

知道了这点,我们就知道,根节点(0x5555557577f0)的左右各有一棵子树,地址分别是0x00005555 55757340, 0x00005555 557572e0

以此类推,可以不断找下去,强烈建议准备一个草稿纸,一步一步画出树的结构,下图是我的草稿(以地址的最后3位为代表,前面均为0x00005555 55757...)。

image-20220907103430132

中间过程我就不再赘述,这里再给出叶子节点(0x00005555 55757320)的例子。

image-20220907103700871

可以看到,320这一行,左边两个单元为空,说明它是叶子节点,那么就可以看第三个单元,就是它的值(int类型)。这时右边两个单元不表示指针,据此也可以更好地理解union

tips:这里有一个坑点,如果用了暗色主题,2a0对应的值可能一时难以发现,如下图

image-20220907103935418

最后画出整棵树,还要注意值都是16进制的,还需要进行进一步的转换,然后从左到右列举,就能得到答案: 6 28 496 8128 33550336 28 28.

标签:char,malloc,pt,int,CS61c,note,地址,str,hw2
From: https://www.cnblogs.com/tsrigo/p/16664584.html

相关文章

  • 在DJango中使用模型类时,出现一个DoesNotExist
    在使用Django去查询数据库时,如果不存在,会抛出一个异常。try:order=Order.objects.get(order_number=order_number)iforder.orde......
  • Hoare Logic Notes
    TheHoareassignmentaxiom\[\vdash\{P[E/V]\}V:=E\{P\}\]TheFloydassignmentaxiom\[\vdash\{P\}V:=E\{\existv.\(V=E[v/V])\wedgeP[v/V]\}\]Preconditi......
  • editplus + notepad++ 列编辑操作
    列编辑//编辑器列选择EditPlus1)菜单:编辑->选择->列选择(Edit->Select->ColumnSelect)2)先按下Alt+C,释放,然后移动鼠标或键盘上下左右键进行列模块的移动注意:......
  • 使用notepad++批量在每行首尾添加内容
    1简介在程序员开发过程中,一个不错的工具是notepad++,该工具为notepad的增强,增强了许多的功能,包括程序员喜欢的列块编辑模式,支持众多的插件,例如json格式化,支持markdown语法......
  • 概率,统计,期望Note
    概率统计期望\(note\)·广义加法公式:\(P(A\cupB)=P(A)+P(B)-P(A\capB)\)应用了容斥原理。·条件概率和乘法公式:\(P(B|A)=\frac{P(A\capB)}{P(A)}\)就是这个等......
  • onenote突然无法同步,同步报错以及创建笔记本都报错问题解决
    同步报错:OneNote当前无法同步笔记。将继续尝试。(错误代码:0x80004005bdf5j)创建笔记本报错:OneNote无法在以下位置新建笔记本打开笔记本报错:无法打开笔记本无法打开......
  • Word 找不到 Endnote选项
    Word2010找不到Endnote选项汇总(不是Office有效加载项)因为基本百度上的问题我全都遇到了…说明:在我们使用Word的过程中,常常发现没有Endnote选项。然后去找百度方法:1.通过......
  • @NotEmpty @NotBlank @NotNull 的区别
    @NotEmpty不能为null,且长度必须大于0,一般用在集合类上或者数组上@NotBlank只能作用在接收的String类型上,注意是只能,不能为null,而且调用trim()后,长度必须大于0,即:......
  • mac的endnote与Word不兼容解决办法
    因为新的Macbookair和Macbookpro使用的是苹果自身的M1芯片,endnotex9和20版本的软件并不兼容这样的芯片,虽然可以用rosetta打开,但是它的word插件确不能被word打开,表现为w......
  • 使用notepad++将每行文本的开头结尾统一加上"",
    引用自:https://blog.csdn.net/lk142500/article/details/83119029背景我们在整理数据或者拼脚本的时候,通常会用到这样的一个场景比如说上传的工资单中的标题栏为以上的......