请懂计算机的朋友指条明路

m
majiaamajia
楼主 (北美华人网)
我们学校里评价高的计算机专业课几乎都是跟system相关的,操作系统的课就有两门,另外还有云计算的系统课,还有分布式系统的课,还有high performance computing的课,也和系统相关。但是跟系统相关的课程都好难啊。不仅是课程难,概念也不好理解,而且这些课都是用C语言的,C语言比java真的是难太多太多了。我的问题是,系统相关的课程对找工作的帮助有多大呢?是不是这类的课程对找C语言的工作,或者system design的底层架构比较有用,如果找全栈或者后端的工作是不是没有必要上这些课了?
请大家帮我解下C语言的疑惑呗。现在讨论适不适合学计算机这个问题已经晚了。我学费已经交了,课也上了三分之一了,不管怎样,还是不想挂科的。大家不如教教我C语言,帮我过这门基础课?多谢啊! 这是我写在第二页的问题。 为什么二级指针比一级指针好?尤其是多线程同步,用二级指针会少很多问题?我问了TA, 但是TA的话,我没看懂。这是TA的原话: X allocated a blob of memory (the pointer of which I''''ll call M) and calls Y. Y then performs some additional processing and calls Z, passing M to Z. When Z detects that the work is done ("hey look, I''''ve processed everything!") it frees M.
"Why would anyone ever do that?" If you were a single developer and you had built X, Y, and Z, then you probably wouldn''''t. But we live in a world in which few developers construct their entire code stack from scratch and instead rely upon using code other developers have written. So the developer that wrote X and Z didn''''t assume that it would be called directly from Y; Y might enqueue the request and handle it later. The author of X knows that Z frees the memory, so it can safely just ignore that pointer once it returns (though it trusts that Y works properly).
Instead,by using double pointer types, we can be explicit about this:
X has a local variable that contains M. Instead of passing the contents of that local variable, it can pass the address of that local variable to Y. Y could then free M and tell X that it had done so by setting the value in X''''''''s local variable to NULL (which we all know is invalid in C and since all OSes are written in C, it means NULL ends up being invalid in essentially all programs, even if they aren''''''''t written in C.) If Y forgets to free the memory, X can also detect this fact because it''''''''s local variable will still contain the address of M and it can clean it up.
Now, if Y repeats this process with Z, Z can free the memory and tell Y. If Y didn''''''''t care about knowing, it can just pass the address to X''''''''s local variable along to Z and the information about what Z did is properly reported back to X. 不胜感谢!
n
nestie
我们学校里评价高的计算机专业课几乎都是跟system相关的,操作系统的课就有两门,另外还有云计算的系统课,还有分布式系统的课,还有high performance computing的课,也和系统相关。但是跟系统相关的课程都好难啊。不仅是课程难,概念也不好理解,而且这些课都是用C语言的,C语言比java真的是难太多太多了。我的问题是,系统相关的课程对找工作的帮助有多大呢?是不是这类的课程对找C语言的工作,或者system design的底层架构比较有用,如果找全栈或者后端的工作是不是没有必要上这些课了?
majiaamajia 发表于 2023-06-23 13:42

你可能不适合学计算机,这是基础课吧
蜂蜜柚子糖
c语言太基本了还是要学的,只会java那是文科转码
K
KOH
如果lz觉得c语言都已经太难,也不想要继续攻克的话,不如考虑转向ds,那python和R就够用。 但很多大厂ds也都是需要资深程序员的
A
Anotherfacet
我们学校里评价高的计算机专业课几乎都是跟system相关的,操作系统的课就有两门,另外还有云计算的系统课,还有分布式系统的课,还有high performance computing的课,也和系统相关。但是跟系统相关的课程都好难啊。不仅是课程难,概念也不好理解,而且这些课都是用C语言的,C语言比java真的是难太多太多了。我的问题是,系统相关的课程对找工作的帮助有多大呢?是不是这类的课程对找C语言的工作,或者system design的底层架构比较有用,如果找全栈或者后端的工作是不是没有必要上这些课了?
majiaamajia 发表于 2023-06-23 13:42

计算机CSE分CS和CE。CS偏应用一些,CE主要是体系结构和高性能计算,偏架构和基础。
从现在的情况看,你可以偏CS一些,CE的课可以少上。首选是ML相关的,然后是cloud相关的。python,java,js都上一些。
不过不做底层的话java应该不比c难多少。
金银岛
看你要找什么样的工作了。如果是当个写application或者website的码农,这些都不需要懂。后端.net或java择其一,前端angular或react择其一,学会了就可以出山了。
小豆
想拿文凭这是core couse吧?
m
majiaamajia
计算机CSE分CS和CE。CS偏应用一些,CE主要是体系结构和高性能计算,偏架构和基础。
从现在的情况看,你可以偏CS一些,CE的课可以少上。首选是ML相关的,然后是cloud相关的。python,java,js都上一些。
不过不做底层的话java应该不比c难多少。
Anotherfacet 发表于 2023-06-23 14:02

感谢!我之前确实都是上偏应用的课,没学过java,也是边上课边学,完全没问题,上得还挺轻松,但是感觉学到的东西非常有限。所以这学期才想着上系统课试试,上系统课的时候也是边上课边学C,但是第一周作业一上来就是二级指针。作业里动不动就一堆memory的bug,每天debug到想哭。。。 请问你说的cloud相关的是我帖子里说的云计算的系统课吗?我们那一门叫cloud computing的也是讲系统的,是一门非常硬的课,上那门课之前要求要上过高级操作系统的课,而且还得拿A,我现在上的是初级操作系统。
s
ss4me
回复 1楼majiaamajia的帖子
我java死活学不会,c却很容易上手
N
NSGA
我们学校里评价高的计算机专业课几乎都是跟system相关的,操作系统的课就有两门,另外还有云计算的系统课,还有分布式系统的课,还有high performance computing的课,也和系统相关。但是跟系统相关的课程都好难啊。不仅是课程难,概念也不好理解,而且这些课都是用C语言的,C语言比java真的是难太多太多了。我的问题是,系统相关的课程对找工作的帮助有多大呢?是不是这类的课程对找C语言的工作,或者system design的底层架构比较有用,如果找全栈或者后端的工作是不是没有必要上这些课了?
majiaamajia 发表于 2023-06-23 13:42

C语言多简单啊,跟英语 差不多,直接。 Java并不容易,要用好它需要有软件工程的概念和基础。 至于你说的这些课程,其实它们是计算机的基础。你即使是做一些应用软件,了解这些对你的程序也是很有帮助的。
x
xcosmos
C语言多简单啊,跟英语 差不多,直接。 Java并不容易,要用好它需要有软件工程的概念和基础。 至于你说的这些课程,其实它们是计算机的基础。你即使是做一些应用软件,了解这些对你的程序也是很有帮助的。
NSGA 发表于 2023-06-23 14:22

按照楼主说的,他可能是对指针比较抽象 其实指针就是一个地址,地址那儿才是运算用的数据 二级指针就是那个地址里面存放的还是一个地址,而不是数据 不知道我这种话说法是不是容易理解点儿
m
majiaamajia
按照楼主说的,他可能是对指针比较抽象 其实指针就是一个地址,地址那儿才是运算用的数据 二级指针就是那个地址里面存放的还是一个地址,而不是数据 不知道我这种话说法是不是容易理解点儿
xcosmos 发表于 2023-06-23 14:45

我知道二级指针放的是一级指针的地址。可是为什么在回调函数的参数里面,二级指针比一级指针好很多呢?我前两周问过TA,TA跟我说用二级指针的话,不会出现多个指针指向同一个变量,用一级指针会有这个问题,然后因为我们的作业是关于多线程的时候,TA说,这样的话一级指针会产生很多问题。我到现在还是有听没有懂。然后我用完回调函数,为什么要在这个回调函数里面把一级指针设置为NULL呢?明明这个回调参数里面用的是二级指针啊。
m
majiaamajia
按照楼主说的,他可能是对指针比较抽象 其实指针就是一个地址,地址那儿才是运算用的数据 二级指针就是那个地址里面存放的还是一个地址,而不是数据 不知道我这种话说法是不是容易理解点儿
xcosmos 发表于 2023-06-23 14:45

另外我还有一个问题, 有一个结构体二级指针A,然后这个结构体里面还包含有另一个结构体的二级指针B。 为什么我已经malloc 完A了,我还必须再malloc一下B呢?难道分配给A的内存空间不包括B的内存空间吗?
x
xcosmos
我知道二级指针放的是一级指针的地址。可是为什么在回调函数的参数里面,二级指针比一级指针好很多呢?我前两周问过TA,TA跟我说用二级指针的话,不会出现多个指针指向同一个变量,用一级指针会有这个问题,然后因为我们的作业是关于多线程的时候,TA说,这样的话一级指针会产生很多问题。我到现在还是有听没有懂。然后我用完回调函数,为什么要在这个回调函数里面把一级指针设置为NULL呢?明明这个回调参数里面用的是二级指针啊。
majiaamajia 发表于 2023-06-23 15:11

这段话对我也好抽象 先问一下,你说的回调函数是指callbacks吗?
x
xcosmos
另外我还有一个问题, 有一个结构体二级指针A,然后这个结构体里面还包含有另一个结构体的二级指针B。 为什么我已经malloc 完A了,我还必须再malloc一下B呢?难道分配给A的内存空间不包括B的内存空间吗?
majiaamajia 发表于 2023-06-23 15:21

当然不包括 因为在A里面的B只是一个地址 不是真正的B 估计只有高手能把你的困难点一句话说明白 我这半罐子有点儿不清不楚
m
majiaamajia
这段话对我也好抽象 先问一下,你说的回调函数是指callbacks吗?
xcosmos 发表于 2023-06-23 15:22

是的。就是callback function, 就是下面这张图。找到了几句TA的原话,我没懂。。。 X allocated a blob of memory (the pointer of which I''ll call M) and calls Y. Y then performs some additional processing and calls Z, passing M to Z. When Z detects that the work is done ("hey look, I''ve processed everything!") it frees M.
"Why would anyone ever do that?" If you were a single developer and you had built X, Y, and Z, then you probably wouldn''t. But we live in a world in which few developers construct their entire code stack from scratch and instead rely upon using code other developers have written. So the developer that wrote X and Z didn''t assume that it would be called directly from Y; Y might enqueue the request and handle it later. The author of X knows that Z frees the memory, so it can safely just ignore that pointer once it returns (though it trusts that Y works properly).
Instead,by using double pointer types, we can be explicit about this:
X has a local variable that contains M. Instead of passing the contents of that local variable, it can pass the address of that local variable to Y. Y could then free M and tell X that it had done so by setting the value in X''''s local variable to NULL (which we all know is invalid in C and since all OSes are written in C, it means NULL ends up being invalid in essentially all programs, even if they aren''''t written in C.) If Y forgets to free the memory, X can also detect this fact because it''''s local variable will still contain the address of M and it can clean it up.
Now, if Y repeats this process with Z, Z can free the memory and tell Y. If Y didn''''t care about knowing, it can just pass the address to X''''s local variable along to Z and the information about what Z did is properly reported back to X. 我做作业一的时候,真的是Debug到想哭啊。对指针对malloc各种搞不明白,动不动就说我内存泄露,动不动就说我overflow,动不动就说client socket hung。所以我对C语言真的是很怕
m
majiaamajia
当然不包括 因为在A里面的B只是一个地址 不是真正的B 估计只有高手能把你的困难点一句话说明白 我这半罐子有点儿不清不楚
xcosmos 发表于 2023-06-23 15:25

不不不,你这么说(A里面的B只是一个地址)我确实听懂了。很感谢!
扶苏
是的。就是callback function, 就是下面这张图。找到了几句TA的原话,我没懂。。。 X allocated a blob of memory (the pointer of which I''''ll call M) and calls Y. Y then performs some additional processing and calls Z, passing M to Z. When Z detects that the work is done ("hey look, I''''ve processed everything!") it frees M.
"Why would anyone ever do that?" If you were a single developer and you had built X, Y, and Z, then you probably wouldn''''t. But we live in a world in which few developers construct their entire code stack from scratch and instead rely upon using code other developers have written. So the developer that wrote X and Z didn''''t assume that it would be called directly from Y; Y might enqueue the request and handle it later. The author of X knows that Z frees the memory, so it can safely just ignore that pointer once it returns (though it trusts that Y works properly).
Instead,by using double pointer types, we can be explicit about this:
X has a local variable that contains M. Instead of passing the contents of that local variable, it can pass the address of that local variable to Y. Y could then free M and tell X that it had done so by setting the value in X''''''''s local variable to NULL (which we all know is invalid in C and since all OSes are written in C, it means NULL ends up being invalid in essentially all programs, even if they aren''''''''t written in C.) If Y forgets to free the memory, X can also detect this fact because it''''''''s local variable will still contain the address of M and it can clean it up.
Now, if Y repeats this process with Z, Z can free the memory and tell Y. If Y didn''''''''t care about knowing, it can just pass the address to X''''''''s local variable along to Z and the information about what Z did is properly reported back to X. 我做作业一的时候,真的是Debug到想哭啊。对指针对malloc各种搞不明白,动不动就说我内存泄露,动不动就说我overflow,动不动就说client socket hung。所以我对C语言真的是很怕

majiaamajia 发表于 2023-06-23 15:26

是不是英文的部分都是TA写的?
第一部分我看懂了。也就是X作为一个class或者object吧,是不能rely on Y去clear memory allocation。这个是黄金原则啊。一般来说,谁allocate memory,谁负责clean up。
在pass variable的时候,就得想清楚保护自己的variable。也就是X不应该给其他任何class direct access of it''s memory。要么pass const pointer,Y不能modify content,或者直接pass by value。
其实对于Programmer来说,我更喜欢dealing C,c++。我最喜欢pointer了。不喜欢那些个garbage collector。尤其对于处理大量数据,直接拿到一个pointer,直接处理,很爽。用table比用什么其他container爽很多。
也就是对于新手来说,memory处理有难度,其实问题关键在于,bad coding habit。只要遵循,who allocate memory, who clean up。never trust other class (or object), so never give other class direct access to your data (这里的you指的是独立的class)。DATA的ownership搞清楚。遵循这些原则,就不会有什么memory leak啦,try to access null pointer啦。
还有,double pointer有必要吗?X自己不能处理自己的data,非得pass 给Y,Y还要pass 给什么Z。写code大忌就是把简单的东西搞复杂。没有必要,pointer就不应该在不同的class之间pass来pass去。Y要做什么? X里面提供一个interface去处理data,让Y去call不行吗?除非绝对没有其他办法,才不得不pass pointer。
写code,设计是最重要的。设计的因素之一就是看你data的动线。谁在allocate,谁在用,谁在free,怎么用,如何集中管理。
把这些事情搞清楚,分清楚stack, heap,对于以后复杂的Multi thread,shared data会有极大的帮助。
m
majiaamajia
是不是英文的部分都是TA写的?
第一部分我看懂了。也就是X作为一个class或者object吧,是不能rely on Y去clear memory allocation。这个是黄金原则啊。一般来说,谁allocate memory,谁负责clean up。
在pass variable的时候,就得想清楚保护自己的variable。也就是X不应该给其他任何class direct access of it''s memory。要么pass const pointer,Y不能modify content,或者直接pass by value。
其实对于Programmer来说,我更喜欢dealing C,c++。我最喜欢pointer了。不喜欢那些个garbage collector。尤其对于处理大量数据,直接拿到一个pointer,直接处理,很爽。用table比用什么其他container爽很多。
也就是对于新手来说,memory处理有难度,其实问题关键在于,bad coding habit。只要遵循,who allocate memory, who clean up。never trust other class (or object), so never give other class direct access to your data (这里的you指的是独立的class)。DATA的ownership搞清楚。遵循这些原则,就不会有什么memory leak啦,try to access null pointer啦。
还有,double pointer有必要吗?X自己不能处理自己的data,非得pass 给Y,Y还要pass 给什么Z。写code大忌就是把简单的东西搞复杂。没有必要,pointer就不应该在不同的class之间pass来pass去。Y要做什么? X里面提供一个interface去处理data,让Y去call不行吗?除非绝对没有其他办法,才不得不pass pointer。
写code,设计是最重要的。设计的因素之一就是看你data的动线。谁在allocate,谁在用,谁在free,怎么用,如何集中管理。
把这些事情搞清楚,分清楚stack, heap,对于以后复杂的Multi thread,shared data会有极大的帮助。
扶苏 发表于 2023-06-23 16:03

是的英文部分都是TA写的。因为作业里面就是用double pointer。我到现在也不理解为啥single pointer不够用?TA是这么解释的,我还是不懂,然后还要在callback里面把*ctx重置为NULL?可是pass 给call back的是**ctx,为啥要*ctx =NULL.
x
xcosmos
是的。就是callback function, 就是下面这张图。找到了几句TA的原话,我没懂。。。 X allocated a blob of memory (the pointer of which I''''ll call M) and calls Y. Y then performs some additional processing and calls Z, passing M to Z. When Z detects that the work is done ("hey look, I''''ve processed everything!") it frees M.
"Why would anyone ever do that?" If you were a single developer and you had built X, Y, and Z, then you probably wouldn''''t. But we live in a world in which few developers construct their entire code stack from scratch and instead rely upon using code other developers have written. So the developer that wrote X and Z didn''''t assume that it would be called directly from Y; Y might enqueue the request and handle it later. The author of X knows that Z frees the memory, so it can safely just ignore that pointer once it returns (though it trusts that Y works properly).
Instead,by using double pointer types, we can be explicit about this:
X has a local variable that contains M. Instead of passing the contents of that local variable, it can pass the address of that local variable to Y. Y could then free M and tell X that it had done so by setting the value in X''''''''s local variable to NULL (which we all know is invalid in C and since all OSes are written in C, it means NULL ends up being invalid in essentially all programs, even if they aren''''''''t written in C.) If Y forgets to free the memory, X can also detect this fact because it''''''''s local variable will still contain the address of M and it can clean it up.
Now, if Y repeats this process with Z, Z can free the memory and tell Y. If Y didn''''''''t care about knowing, it can just pass the address to X''''''''s local variable along to Z and the information about what Z did is properly reported back to X. 我做作业一的时候,真的是Debug到想哭啊。对指针对malloc各种搞不明白,动不动就说我内存泄露,动不动就说我overflow,动不动就说client socket hung。所以我对C语言真的是很怕

majiaamajia 发表于 2023-06-23 15:26

妹子,我很久没有写C了,所以一时半会儿还真没看懂你这张图,但我想说几点: 1,你首先要从心里上就不要觉得C难,或者指针难,带入情绪很难冷静分析问题,尤其是debug的时候,你别给自己压力太大,慢慢来,debug本来就是很漫长的过程 2,要分清楚object/就是具体的data和handle to data(object)/或者说指针的概念,不管是java还是python,你前面那个struct里面有struct的问题都会遇到,对于B的内存分配都要单独进行 3,你说的二级指针问题我没看懂,但我们用二级指针是为了灵活方便,这个指针可以存任何地址,也就是任何指针,那么这个二级指针就可以存放不受type限制的数据了,而一级指针是受限制的,所以你们TA的说法我没看明白,你确定他是那个意思吗? 4,前面这个图里被赋值null的不是一级指针,是二级指针。ctx是二级指针的地址,*ctx是二级指针的内容,被清空为null,**ctx才是真的内容。这里就是把二级指针清空了,不再指向任何数据的地址,但在清空之前,被复制了

h
huaren_2018
看去做啥开发,应用开发,这些基本不用。
A
Anotherfacet
是的。就是callback function, 就是下面这张图。找到了几句TA的原话,我没懂。。。 X allocated a blob of memory (the pointer of which I''ll call M) and calls Y. Y then performs some additional processing and calls Z, passing M to Z. When Z detects that the work is done ("hey look, I''ve processed everything!") it frees M.
"Why would anyone ever do that?" If you were a single developer and you had built X, Y, and Z, then you probably wouldn''t. But we live in a world in which few developers construct their entire code stack from scratch and instead rely upon using code other developers have written. So the developer that wrote X and Z didn''t assume that it would be called directly from Y; Y might enqueue the request and handle it later. The author of X knows that Z frees the memory, so it can safely just ignore that pointer once it returns (though it trusts that Y works properly).
Instead,by using double pointer types, we can be explicit about this:
X has a local variable that contains M. Instead of passing the contents of that local variable, it can pass the address of that local variable to Y. Y could then free M and tell X that it had done so by setting the value in X''''s local variable to NULL (which we all know is invalid in C and since all OSes are written in C, it means NULL ends up being invalid in essentially all programs, even if they aren''''t written in C.) If Y forgets to free the memory, X can also detect this fact because it''''s local variable will still contain the address of M and it can clean it up.
Now, if Y repeats this process with Z, Z can free the memory and tell Y. If Y didn''''t care about knowing, it can just pass the address to X''''s local variable along to Z and the information about what Z did is properly reported back to X. 我做作业一的时候,真的是Debug到想哭啊。对指针对malloc各种搞不明白,动不动就说我内存泄露,动不动就说我overflow,动不动就说client socket hung。所以我对C语言真的是很怕

majiaamajia 发表于 2023-06-23 15:26

It means if you use **ctx, you have an extra level of small memory that X, Y and Z can all access. That memory could be the either *ctx or NULL. If it is NULL it means Y has freed M and is done.
If you only use *ctx then you don't have such a small memory that X, Y and Z can all access and share some info.
========================
But this is like last-century knowledge; in today's industry we mostly use smart pointers (e.g. unique pointer), which has clear ownership and it has no such an ownership issue.
S
Sleepy3824
楼主看来是卡在一个概念上了,能拐过弯就好了。
其实大学,研究生的课绝大多数都没什么直接用处,但是训练了一种思维能力,和对计算机系统一个整体的理解,help you to make better decision down the road。你说多少人工作中需要面对网络七层?
我觉得对我上学时最有用的一门课是OS,被逼着写了个核,除了学到多线程,内存管理,各种驱动器预留借口,更关键的自己一边哭一边写了这么大(对学生而言)一个东西。写完了debug了跑起来了才第一次觉得自己可以成为一个IT从业者。

x
xcosmos
回复完发现妹子加了这么多内容,我再看一会儿
s
ss4me
回复 22楼Anotherfacet的帖子
敲黑板,这里是C语言
t
ted.hanks
因为C用的是by value, java 用的是by reference
callee 在函数内部是无法改变caller 那边的指针的值, 所以一旦callee free memory, caller 那边就有一个dangling 指针。 而传double pointer, callee 是可以改变caller 那边的值, 相当于pass by reference。但是caller 那边编译器可能直接把指针优化了, 可以考虑用volatile。
anyway, c 太灵活,对内存管理太primitve, 要么用convention, 要么干脆上c++的smart pointer, 或者rust 的borrow check。


c
coalpilerd
我知道二级指针放的是一级指针的地址。可是为什么在回调函数的参数里面,二级指针比一级指针好很多呢?我前两周问过TA,TA跟我说用二级指针的话,不会出现多个指针指向同一个变量,用一级指针会有这个问题,然后因为我们的作业是关于多线程的时候,TA说,这样的话一级指针会产生很多问题。我到现在还是有听没有懂。然后我用完回调函数,为什么要在这个回调函数里面把一级指针设置为NULL呢?明明这个回调参数里面用的是二级指针啊。
majiaamajia 发表于 2023-06-23 15:11

用二级指针因为C语言里只有值参没有变参啊。你把一级指针作为参数传递给一个函数,这函数只能free一级指针,但是没法把这个一级指针设为NULL。如果参数是个二级指针,就可以把二级指针指向的一级指针free完了之后设为零。 为什么free完了要设为零?因为这个一级指针可能有很多其他线程在用,设为零方便其他线程知道指针被free了,可以避免其他人再去读写或者二次free。
x
xcosmos
是不是英文的部分都是TA写的?
第一部分我看懂了。也就是X作为一个class或者object吧,是不能rely on Y去clear memory allocation。这个是黄金原则啊。一般来说,谁allocate memory,谁负责clean up。
在pass variable的时候,就得想清楚保护自己的variable。也就是X不应该给其他任何class direct access of it''s memory。要么pass const pointer,Y不能modify content,或者直接pass by value。
其实对于Programmer来说,我更喜欢dealing C,c++。我最喜欢pointer了。不喜欢那些个garbage collector。尤其对于处理大量数据,直接拿到一个pointer,直接处理,很爽。用table比用什么其他container爽很多。
也就是对于新手来说,memory处理有难度,其实问题关键在于,bad coding habit。只要遵循,who allocate memory, who clean up。never trust other class (or object), so never give other class direct access to your data (这里的you指的是独立的class)。DATA的ownership搞清楚。遵循这些原则,就不会有什么memory leak啦,try to access null pointer啦。
还有,double pointer有必要吗?X自己不能处理自己的data,非得pass 给Y,Y还要pass 给什么Z。写code大忌就是把简单的东西搞复杂。没有必要,pointer就不应该在不同的class之间pass来pass去。Y要做什么? X里面提供一个interface去处理data,让Y去call不行吗?除非绝对没有其他办法,才不得不pass pointer。
写code,设计是最重要的。设计的因素之一就是看你data的动线。谁在allocate,谁在用,谁在free,怎么用,如何集中管理。
把这些事情搞清楚,分清楚stack, heap,对于以后复杂的Multi thread,shared data会有极大的帮助。
扶苏 发表于 2023-06-23 16:03

这个妹子写的几条基本原则,我也要牢记
扶苏
因为C用的是by value, java 用的是by reference
callee 在函数内部是无法改变caller 那边的指针的值, 所以一旦callee free memory, caller 那边就有一个dangling 指针。 而传double pointer, callee 是可以改变caller 那边的值, 相当于pass by reference。但是caller 那边编译器可能直接把指针优化了, 可以考虑用volatile。
anyway, c 太灵活,对内存管理太primitve, 要么用convention, 要么干脆上c++的smart pointer, 或者rust 的borrow check。



ted.hanks 发表于 2023-06-23 16:19

C和java都可以pass by reference pass by value。
A
Anotherfacet
回复 22楼Anotherfacet的帖子
敲黑板,这里是C语言
ss4me 发表于 2023-06-23 16:17

Unless she wants to work on kernel/driver/... low level stuff (which I think highly unlikely), such C level knowledge is not useful.
I think the universities should teach the students more marketable C++11/14/17 in school.
c
coalpilerd
C和java都可以pass by reference pass by value。

扶苏 发表于 2023-06-23 16:26

C所谓的pass by reference就是用指针做参数,C++倒是可以用&表示pass by reference。
t
ted.hanks
C和java都可以pass by reference pass by value。

扶苏 发表于 2023-06-23 16:26

java 的 primitive type 可以pass by value, object 应该都是pass by reference。 但是c 应该是没有pass by reference的, C++ 有。
g
gokgs
哈哈, 这个是 hard core CS. C 是基本功, 除了 C++ 别的都是垃圾语言。 哈哈
t
ted.hanks
Unless she wants to work on kernel/driver/... low level stuff (which I think highly unlikely), such C level knowledge is not useful.
I think the universities should teach the students more marketable C++11/14/17 in school.
Anotherfacet 发表于 2023-06-23 16:26

不用太low, 有同事写java, python, 也用jni 和c extension 的。 很多时候c lib 已经有了, 写个ffi 快很多。
g
gokgs
你可能不适合学计算机,这是基础课吧
nestie 发表于 2023-06-23 13:56

操作系统, 编译原理都不太容易, 不过都是基础课。
b
bigtime
看完了讨论,感觉华人大妈虽然天天嘲笑小红书转码美女,但是拿到FAANG offer的小红书美女水平碾压这里的大妈们
g
gokgs
回复 1楼majiaamajia的帖子
我java死活学不会,c却很容易上手
ss4me 发表于 2023-06-23 14:19

Java python 都是垃圾语言。 C 学会了, 别的都很简单, 学点 OOP 基本概念就够了, C 没有 OOP。
s
smileCy
C语言多简单啊,跟英语 差不多,直接。 Java并不容易,要用好它需要有软件工程的概念和基础。 至于你说的这些课程,其实它们是计算机的基础。你即使是做一些应用软件,了解这些对你的程序也是很有帮助的。
NSGA 发表于 2023-06-23 14:22

现在谁用c啊,java比c简单多了
g
gokgs
C所谓的pass by reference就是用指针做参数,C++倒是可以用&表示pass by reference。
coalpilerd 发表于 2023-06-23 16:28

pass by reference 本质上就是 pass by pointer. pass by pointer 本质上也是是 pass by value, 也就是说底层都是 pass by value.
g
gokgs
java 的 primitive type 可以pass by value, object 应该都是pass by reference。 但是c 应该是没有pass by reference的, C++ 有。

ted.hanks 发表于 2023-06-23 16:29

java 这些垃圾语言都是蒙人的, 什么 pass by reference 都是鬼扯, 其实都是 pointer 当 reference 用, 你遇到 null pointer access 就知道了。 真正的 pass by reference 是不会有 null pointer 的。
扶苏
是的英文部分都是TA写的。因为作业里面就是用double pointer。我到现在也不理解为啥single pointer不够用?TA是这么解释的,我还是不懂,然后还要在callback里面把*ctx重置为NULL?可是pass 给call back的是**ctx,为啥要*ctx =NULL.
majiaamajia 发表于 2023-06-23 16:08

很简单,pointer就是地址。double pointer就是地址的地址。比如你寄包裹,但是你的包裹里不装东西,而是装了一个地址。收到信的人直接去那个地址拿东西。
double pointer就是,你给的地址,去到那里,拿到的又是一个地址。
一般double pointer用在two dimension array上。如果说用在你TA写的东西上,我个人觉得纯粹浪费,不elegant,也不efficient。
不过你在学习,所以需要你通过coding来理解double pointer。其实就是地址的地址。很好理解。或者你可以理解为pointer 就是箭头,指向某个东西。single pointer指向实际的data,double pointer就是指向一个singe pointer,然后refenrece这个single pointer可以找到data。
反正就是一个寻找宝藏的游戏。拿到藏宝图,而去了目的地发现没有宝藏,而是另外一个藏宝图,就是这样。没什么复杂的。你null了double pointer指向的东西,就等于把第二张藏宝图给毁了。但是宝藏没事。也就是你的data没事。好像是这个意思吧。你如果拿着二级藏宝图,先找到一级藏宝图,然后才能知道宝藏在哪。才能去到宝藏的地点。也就是这样。如果再复杂一点,就是triple pointer, 想加几个加几个。问题是实际操作中,有意思吗?除了迷惑看自己code的人,计算机根本不care。把人搞晕了,最对达到一个娱乐效果,哈哈。
所以实际操作中,根本不会轻易用到double pointer,更不要说triple pointer了。
c
coalpilerd
pass by reference 本质上就是 pass by pointer. pass by pointer 本质上也是是 pass by value, 也就是说底层都是 pass by value.
gokgs 发表于 2023-06-23 16:34

这么说也有道理。反正在C这个大前提之下,一切都按照最底层的来就对了。
g
gokgs
现在谁用c啊,java比c简单多了
smileCy 发表于 2023-06-23 16:33

cisco 那些 router 老程序 估计还是 c, 不可能有人重写。
我面试就碰到一个, c++ 都不会, 只会 c. 哈哈。
C 其实是最基本的。 我们上大学时就学的 C, 别的都是毕业后慢慢自己学的。
s
squirrel40
C语言多简单啊,跟英语 差不多,直接。 Java并不容易,要用好它需要有软件工程的概念和基础。 至于你说的这些课程,其实它们是计算机的基础。你即使是做一些应用软件,了解这些对你的程序也是很有帮助的。
NSGA 发表于 2023-06-23 14:22

C语言简单。 但是需要用C语言的地方都是直接和寄存器,内存打交道的地方。 需要对计算机体系有深入的理解
A
Anotherfacet
I am in one of FANG. 90% of the NCG students'''' resumes I received are very, very, very similar. All are ML projects, ML projects, and ML projects. So I never ask their background now and just test their coding ability directly.
C? That is last-century knowledge. There are some C openings for sure; but they are not for average graduates today.
扶苏
C所谓的pass by reference就是用指针做参数,C++倒是可以用&表示pass by reference。
coalpilerd 发表于 2023-06-23 16:28

C c++ c# 我经常记不清楚具体的call。概念上pass by reference就是pass 地址。也就是heap memory。当然了C好像是没有&这个概念。不过无所谓吧,对于programmer来说,基础的概念是一样的。
其实越简单,overhead越小的语言,比如C才是最efficient,自由度最大,也最容易控制的。我反倒不喜欢java。可能我经常跟低层,driver之类的打交道。c++是常备,C偶尔会用到。
半个马和甲
嗯。没看懂问题。 Single and double pointer 好像没有好坏之分?
不过set to null , avoid double freeing . Single pointer, on the other hand , cannot be set to null. Double free is bad .... That''s how things crush . Forgetting to free is also bad , that''s how memory leak begins.
So we set the second the pointer to null so even if you forget to free after malloc , you are still not screwed
至于什么是double pointer , 这个概念,
妹子画个图?



半个马和甲
很简单,pointer就是地址。double pointer就是地址的地址。比如你寄包裹,但是你的包裹里不装东西,而是装了一个地址。收到信的人直接去那个地址拿东西。
double pointer就是,你给的地址,去到那里,拿到的又是一个地址。
一般double pointer用在two dimension array上。如果说用在你TA写的东西上,我个人觉得纯粹浪费,不elegant,也不efficient。
不过你在学习,所以需要你通过coding来理解double pointer。其实就是地址的地址。很好理解。或者你可以理解为pointer 就是箭头,指向某个东西。single pointer指向实际的data,double pointer就是指向一个singe pointer,然后refenrece这个single pointer可以找到data。
反正就是一个寻找宝藏的游戏。拿到藏宝图,而去了目的地发现没有宝藏,而是另外一个藏宝图,就是这样。没什么复杂的。你null了double pointer指向的东西,就等于把第二张藏宝图给毁了。但是宝藏没事。也就是你的data没事。好像是这个意思吧。你如果拿着二级藏宝图,先找到一级藏宝图,然后才能知道宝藏在哪。才能去到宝藏的地点。也就是这样。如果再复杂一点,就是triple pointer, 想加几个加几个。问题是实际操作中,有意思吗?除了迷惑看自己code的人,计算机根本不care。把人搞晕了,最对达到一个娱乐效果,哈哈。
所以实际操作中,根本不会轻易用到double pointer,更不要说triple pointer了。
扶苏 发表于 2023-06-23 16:37

Re : double pointer = 2D array . 给你找了个图,比文字要形象
First pointer 指向 address of the variable Second pointer 指向 address of the first pointer (如此就可以modify with effects outside function 了)
c
coalpilerd
很简单,pointer就是地址。double pointer就是地址的地址。比如你寄包裹,但是你的包裹里不装东西,而是装了一个地址。收到信的人直接去那个地址拿东西。
double pointer就是,你给的地址,去到那里,拿到的又是一个地址。
一般double pointer用在two dimension array上。如果说用在你TA写的东西上,我个人觉得纯粹浪费,不elegant,也不efficient。
不过你在学习,所以需要你通过coding来理解double pointer。其实就是地址的地址。很好理解。或者你可以理解为pointer 就是箭头,指向某个东西。single pointer指向实际的data,double pointer就是指向一个singe pointer,然后refenrece这个single pointer可以找到data。
反正就是一个寻找宝藏的游戏。拿到藏宝图,而去了目的地发现没有宝藏,而是另外一个藏宝图,就是这样。没什么复杂的。你null了double pointer指向的东西,就等于把第二张藏宝图给毁了。但是宝藏没事。也就是你的data没事。好像是这个意思吧。你如果拿着二级藏宝图,先找到一级藏宝图,然后才能知道宝藏在哪。才能去到宝藏的地点。也就是这样。如果再复杂一点,就是triple pointer, 想加几个加几个。问题是实际操作中,有意思吗?除了迷惑看自己code的人,计算机根本不care。把人搞晕了,最对达到一个娱乐效果,哈哈。
所以实际操作中,根本不会轻易用到double pointer,更不要说triple pointer了。
扶苏 发表于 2023-06-23 16:37

二级指针用到的地方多了去了。举个例子,函数返回值是error code(linux kernel里头一大堆这种函数),input和output都只能是参数,如果某个output就是个地址呢?那这个做output的参数就得是二级指针,方便函数写进去一个一级指针嘛。那个TA说的也没啥问题,一个内存块几个线程用,大家都拿着同一个二级指针,然后某个线程把内存free之后顺便清零了二级指针,挺常见的操作么;总比大家都拿着一级指针、其中某线程把内存给free了,其他的线程还不知道,各种invalid read、invalid write好吧。
三级指针的确少见。
t
ted.hanks
pass by reference 本质上就是 pass by pointer. pass by pointer 本质上也是是 pass by value, 也就是说底层都是 pass by value.
gokgs 发表于 2023-06-23 16:34

也对也不对。 取决于reference是怎么实现的。
比如你可以用地址来实现reference, 也可以用handle。 用了handle 就可以解耦object 和 地址了, 后面的gc 能做更多的优化。
m
maodouchong
看看就,mark
t
ted.hanks
二级指针用到的地方多了去了。举个例子,函数返回值是error code(linux kernel里头一大堆这种函数),input和output都只能是参数,如果某个output就是个地址呢?那这个做output的参数就得是二级指针,方便函数写进去一个一级指针嘛。那个TA说的也没啥问题,一个内存块几个线程用,大家都拿着同一个二级指针,然后某个线程把内存free之后顺便清零了二级指针,挺常见的操作么;总比大家都拿着一级指针、其中某线程把内存给free了,其他的线程还不知道,各种invalid read、invalid write好吧。
三级指针的确少见。
coalpilerd 发表于 2023-06-23 17:01

多维数组啊, 想要几级有几级。
王力宏
学语言是cs里最容易的part吧。c 又是语言里最容易的,直来直去没有任何magic。
半个马和甲
最后妹子加油! 如果你现在有可以支持自己生活的工作。别轻易放弃这个学习啊。 有些时候是难,但学什么不是一开始一头雾水的(学霸们除外).
还有除了这里,你还可以去
Stock overflow Geekstogeeks.org
那些比较专业扎堆的地方。特别后者写的东西简洁又好懂。初学者也看得懂的
g
gokgs
C语言简单。 但是需要用C语言的地方都是直接和寄存器,内存打交道的地方。 需要对计算机体系有深入的理解
squirrel40 发表于 2023-06-23 16:39

深入的了解也谈不上, 在哪一层干活就是了。 C 也不一定用到寄存器。
g
gokgs
也对也不对。 取决于reference是怎么实现的。
比如你可以用地址来实现reference, 也可以用handle。 用了handle 就可以解耦object 和 地址了, 后面的gc 能做更多的优化。
ted.hanks 发表于 2023-06-23 17:08

靠,你老还 handle 呢? handle 是个什么狗屁东东? 你这么外行?
讲 handle 的都是门外汉 for sure.
g
gokgs
学语言是cs里最容易的part吧。c 又是语言里最容易的,直来直去没有任何magic。
王力宏 发表于 2023-06-23 17:20

你老也是同行阿? 哈哈。
20 年前面试都问 c++ virture function 什么的, 现在没人问语言了, 基本假设你用不着两天就会学会了。
c 是 入门语言, 也不能说很容易, 毕竟是第一门语言。
刚开始编程的时候, 最纳闷的就是明明知道我少了个分号, 为什么不自动给我加上? 哈哈。
g
gokgs
C语言简单。 但是需要用C语言的地方都是直接和寄存器,内存打交道的地方。 需要对计算机体系有深入的理解
squirrel40 发表于 2023-06-23 16:39

你这个明显不懂为什么有 C。
w
webdriver
很简单,pointer就是地址。double pointer就是地址的地址。比如你寄包裹,但是你的包裹里不装东西,而是装了一个地址。收到信的人直接去那个地址拿东西。
double pointer就是,你给的地址,去到那里,拿到的又是一个地址。
一般double pointer用在two dimension array上。如果说用在你TA写的东西上,我个人觉得纯粹浪费,不elegant,也不efficient。
不过你在学习,所以需要你通过coding来理解double pointer。其实就是地址的地址。很好理解。或者你可以理解为pointer 就是箭头,指向某个东西。single pointer指向实际的data,double pointer就是指向一个singe pointer,然后refenrece这个single pointer可以找到data。
反正就是一个寻找宝藏的游戏。拿到藏宝图,而去了目的地发现没有宝藏,而是另外一个藏宝图,就是这样。没什么复杂的。你null了double pointer指向的东西,就等于把第二张藏宝图给毁了。但是宝藏没事。也就是你的data没事。好像是这个意思吧。你如果拿着二级藏宝图,先找到一级藏宝图,然后才能知道宝藏在哪。才能去到宝藏的地点。也就是这样。如果再复杂一点,就是triple pointer, 想加几个加几个。问题是实际操作中,有意思吗?除了迷惑看自己code的人,计算机根本不care。把人搞晕了,最对达到一个娱乐效果,哈哈。
所以实际操作中,根本不会轻易用到double pointer,更不要说triple pointer了。
扶苏 发表于 2023-06-23 16:37

可以用于增加程序的抗反编译(obfuscation) LOL
w
webdriver
确实C太太tm简单了,C++或者其他高级语言为了增加语言通用性引进无数的语法糖的才变态,当年为了debug引入泛型模板之类的code,简直让人吐血啊 哪像C代码,GDB一起啥事尽在掌握当中

b
bluefly21
作为入门语言,C确实挺难的,需要花很多时间去处理指针之类的东西,但是C也很有用,你觉得难的地方是因为很多不会,学会了就不难了,而且这个是非常基础的东西,对你将来还是很有帮助的 等你指针那一套学明白了,就可以不再用C,换其他高级一点语言,所谓高级就是把指针帮你弄了。那时候你会发现所有的语言差不多,logic都是相同的
还有一些心得,你说的那些课程,对你面试没什么太大用,但是长远看来是需要的。你不可能一辈子当个junior engineer,越senior,就越需要对system的理解。 你现在辛苦的啃下来,将来学东西,理解东西就会更快,现在觉得难跳过去将来有一天还是得学。
现在学的好处是你将来可以做的面就比较广,以后学的好处是你可以挑你已经有经验的方向相关的学,能比现在稍微少一点。 现在学的坏处就是花的时间比较久,对面试没有直接帮助。以后学的坏处是你工作的组怎么样不可控,不知道会不会给你足够的时间ramp up,工作之后的表现可能相对没那么好。
g
gvcc
LZ以前文科生吧,指向指针的指针是很基础的概念,方便直接修改变量值,或者改变一级指针的指向。
半个马和甲
作为入门语言,C确实挺难的,需要花很多时间去处理指针之类的东西,但是C也很有用,你觉得难的地方是因为很多不会,学会了就不难了,而且这个是非常基础的东西,对你将来还是很有帮助的 等你指针那一套学明白了,就可以不再用C,换其他高级一点语言,所谓高级就是把指针帮你弄了。那时候你会发现所有的语言差不多,logic都是相同的
还有一些心得,你说的那些课程,对你面试没什么太大用,但是长远看来是需要的。你不可能一辈子当个junior engineer,越senior,就越需要对system的理解。 你现在辛苦的啃下来,将来学东西,理解东西就会更快,现在觉得难跳过去将来有一天还是得学。
现在学的好处是你将来可以做的面就比较广,以后学的好处是你可以挑你已经有经验的方向相关的学,能比现在稍微少一点。 现在学的坏处就是花的时间比较久,对面试没有直接帮助。以后学的坏处是你工作的组怎么样不可控,不知道会不会给你足够的时间ramp up,工作之后的表现可能相对没那么好。
bluefly21 发表于 2023-06-23 18:39

手动点赞。趁着年轻基础打好。 多去看看那些pointer to printer examples (网上一大堆 - 最好的是那种错误的写法和正确的写法都列出来的那种) , 看完,自己演练下,一个不行,就10个(别小看题海技术- 有些时候就是做着做着开窍了)。
s
ss4me
cisco 那些 router 老程序 估计还是 c, 不可能有人重写。
我面试就碰到一个, c++ 都不会, 只会 c. 哈哈。
C 其实是最基本的。 我们上大学时就学的 C, 别的都是毕业后慢慢自己学的。
gokgs 发表于 2023-06-23 16:38

你碰到的不会是我吧
g
gokgs
你碰到的不会是我吧
ss4me 发表于 2023-06-23 18:58

哈哈,那个是烙印。
半个马和甲
不知道妹子还需不需要, 看下这两道题,懂了就懂fundamental knowledge 来了
Void sub (int a ) {a=a-1; } Void sub (int *a) { *a=*a-1;}
{
Int x=10; Sub (x) ; Sub (&x);
两个数字分别是几呢?
然后想下如果需要modify 正好是个pointer 呢? 怎么办呢? 咦,是不是答案的样子有些熟悉啊?
至于为什么不直接value , 因为有些什么真的Size很大啊。 但address 就不一样了。
希望以此可以对你有帮助。最后别灰心再次别听那些学会后的发言,C是个很大的思维转变。没有谁第一次就懂的。⛽
f
fs1
讲一个好玩的:
你吹了一个气球,一头系在线上,把线和气球给你朋友Y玩,Y也可能把它给她的朋友Z玩。
如果你不管她们最后把气球怎样,你就完事了。
如果你要保证气球玩完后要被戳破,那你就要检查。YZ戳破都可以,但是如果她们没有,你就要把它戳破。
怎么检查呢?人容易。你还有线,沿着线看去,气球破没破一眼就看出来了。
电脑不行。如果你看或者碰或者戳已经破的气球,你的程序会炸掉。破气球变炸弹了。
怎么办呢?你可以让她们玩完后直接告诉你她们有没有把气球戳破。如果她们没办法直接告诉你,可以想办法让她们间接告诉你。比如你给她们一个梭子,上面缠着气球的线。如果她们把气球戳破了,她们把线从梭子上去掉,梭子上面没有线,这样你就知道气球破了。如果你看到梭子上还有线,你就要把气球戳破。
如果她们没有把气球戳破,但是把线从梭子上去掉了,你没办法。气球有没有被戳破只有听天由命了。
如果她们淘气,把气球戳破,但是没有把线从梭子上去掉,所以你再去戳破气球,你的程序会炸掉。
气球:M 线:一级指针 梭子:二级指针 梭子上没有线:二级指针指向NULL 戳破:free 戳破的气球:freed memory 看或者碰或者戳已经破的气球:FMR (free memory read) 程序炸掉:segmentation fault
蜂蜜柚子糖
看你们讲得好有意思,我也想去学一学了
m
mywish
LZ, 我不是计算机专业,但以前也有学习C语言,感觉不难。
也许你可以找一些中文教材,中文理解快一些,有基础后然后再看英文?可以试试这个方法。
一年明月
我感觉后端/全栈的工作对system knowledge的要求比前端多一些。
你们TA说的这个二级指针比一级指针好的论点我感觉其实没有很大说服力。当A,B,C是互不相干的模块时,让B去free A allocate的memory挺不规范的,你怎么知道A就没用了呢?这里如果需要transfer memory ownership给B,应当在API的层面规定好,transfer以后A就得与它一别两宽,再无交集,绝对不可以再碰。说B可能free也可能忘记,所以需要A来擦屁股的这种设计方法在略微复杂的程序里是会让人疯掉的。🤣
比如你们TA说的,A把M交给B,B把它放到一个queue里去等将来再处理(多线程Async),工作还没做完就返回了。这时A发现M还没有被free掉就把它free掉了,然后等M排队排到Queue的第一个的时候,里面的内容就是垃圾了…… 感觉多线程更要注意数据归属的问题呀。
p
psyentistc
要是大厂找工作,还是搞搞算法刷刷题,想办法过面试。其他很多东西都是现学现用就可以了。写码我感觉都是边学边会的,而且基本随便什么role都一直得学新东西。面试主要是看看有没有基础概念(能不能尽快干活),然后人聪不聪明(以后学得快不快)。C没必要死磕吧,实际上用得也不多,很多现代PL的概念也没有。
w
wormcc
用二级指针因为C语言里只有值参没有变参啊。你把一级指针作为参数传递给一个函数,这函数只能free一级指针,但是没法把这个一级指针设为NULL。如果参数是个二级指针,就可以把二级指针指向的一级指针free完了之后设为零。 为什么free完了要设为零?因为这个一级指针可能有很多其他线程在用,设为零方便其他线程知道指针被free了,可以避免其他人再去读写或者二次free。
coalpilerd 发表于 2023-06-23 16:19

作为一个上个世纪用c做作业的老人,从头看到尾只有这个答案最直接明了
S
SecretKey2
我在学校里最不想写就是c
g
gaziou
楼上说的对
g
gaziou
楼主加油!
l
littlefisher38
看看就,mark
一年明月
作为一个上个世纪用c做作业的老人,从头看到尾只有这个答案最直接明了
wormcc 发表于 2023-06-24 07:44

你说得对,但是多线程时不知道谁会free这个指针,听起来有点吓人。😅 这么随便传来传去的话,读写的时候怎样锁住数据避免race?
千渔千寻
回复 1楼majiaamajia的帖子
有EECS的老公或男友么?最靠谱的。
千渔千寻
回复 1楼majiaamajia的帖子
写的是乱七八糟的。猜一下。
指针是指向一段分配(malloc)的内存单元的起始地址。二级指针(指针的指针)是另有一个内存单元把这个起始地址当值存在,该内存单元也有起始地址;这个起始地址就是二级指针。
XYZ就是函数内call函数。你把这个二级指针作为参数传进去,X-》Y-》Z,Z做完工作,这段内存单元就可以释放了,就可以free了这段内存;然后再把二级指针处的值给改为NULL,就表示Z已经带你(Y/X)做了释放内存的工作了。Z运行结束,跳回到Y函数,Y函数一看二级指针处的值给改为NULL,就说明已经释放过内存了;不然Y进行free,再把二级指针处的值给改为NULL。
Y运行结束,跳回到X函数,X函数一看二级指针处的值给改为NULL,就说明之前已经释放过内存了;不然X进行free,再把二级指针处的值给改为NULL。

千渔千寻
回复 1楼majiaamajia的帖子
你java都没入门。java是用C++开发的。有些地方是要写java native interface的,也是要对接cpp的dll或so的。
m
molly233
我们学校里评价高的计算机专业课几乎都是跟system相关的,操作系统的课就有两门,另外还有云计算的系统课,还有分布式系统的课,还有high performance computing的课,也和系统相关。但是跟系统相关的课程都好难啊。不仅是课程难,概念也不好理解,而且这些课都是用C语言的,C语言比java真的是难太多太多了。我的问题是,系统相关的课程对找工作的帮助有多大呢?是不是这类的课程对找C语言的工作,或者system design的底层架构比较有用,如果找全栈或者后端的工作是不是没有必要上这些课了?
请大家帮我解下C语言的疑惑呗。现在讨论适不适合学计算机这个问题已经晚了。我学费已经交了,课也上了三分之一了,不管怎样,还是不想挂科的。大家不如教教我C语言,帮我过这门基础课?多谢啊! 这是我写在第二页的问题。 为什么二级指针比一级指针好?尤其是多线程同步,用二级指针会少很多问题?我问了TA, 但是TA的话,我没看懂。这是TA的原话: X allocated a blob of memory (the pointer of which I''''''''ll call M) and calls Y. Y then performs some additional processing and calls Z, passing M to Z. When Z detects that the work is done ("hey look, I''''''''ve processed everything!") it frees M.
"Why would anyone ever do that?" If you were a single developer and you had built X, Y, and Z, then you probably wouldn''''''''t. But we live in a world in which few developers construct their entire code stack from scratch and instead rely upon using code other developers have written. So the developer that wrote X and Z didn''''''''t assume that it would be called directly from Y; Y might enqueue the request and handle it later. The author of X knows that Z frees the memory, so it can safely just ignore that pointer once it returns (though it trusts that Y works properly).
Instead,by using double pointer types, we can be explicit about this:
X has a local variable that contains M. Instead of passing the contents of that local variable, it can pass the address of that local variable to Y. Y could then free M and tell X that it had done so by setting the value in X''''''''''''''''s local variable to NULL (which we all know is invalid in C and since all OSes are written in C, it means NULL ends up being invalid in essentially all programs, even if they aren''''''''''''''''t written in C.) If Y forgets to free the memory, X can also detect this fact because it''''''''''''''''s local variable will still contain the address of M and it can clean it up.
Now, if Y repeats this process with Z, Z can free the memory and tell Y. If Y didn''''''''''''''''t care about knowing, it can just pass the address to X''''''''''''''''s local variable along to Z and the information about what Z did is properly reported back to X. 不胜感谢!
majiaamajia 发表于 2023-06-23 13:42

C语言国内大学非计算机专业都是必修。你计算机专业学的竟然觉得难。。
计算机专业的随便什么新语言都是自学个几天就行了,根本不需要上课。上课学的是理论
千渔千寻
回复 23楼Sleepy3824的帖子
需要的吧。现在主流是说网络5层。
应用层互联网码农天天接触,不同说。传输层TCP的端口,网络层的IP地址,数据链接层的MAC地址。除了物理层都会接触到啊。我们公司的新电脑加入公司网络,都要你告诉MAC address,加入白名单才可以啊。

千渔千寻
回复 55楼gokgs的帖子
内联汇编啊。C 这种procedural programming lang。就是因为编译出来的汇编码是顺序的,old C code monkey都能猜出来编译出来的是啥,可以加自己的汇编段啊。

P
PLAZZZ1
感谢!我之前确实都是上偏应用的课,没学过java,也是边上课边学,完全没问题,上得还挺轻松,但是感觉学到的东西非常有限。所以这学期才想着上系统课试试,上系统课的时候也是边上课边学C,但是第一周作业一上来就是二级指针。作业里动不动就一堆memory的bug,每天debug到想哭。。。 请问你说的cloud相关的是我帖子里说的云计算的系统课吗?我们那一门叫cloud computing的也是讲系统的,是一门非常硬的课,上那门课之前要求要上过高级操作系统的课,而且还得拿A,我现在上的是初级操作系统。
majiaamajia 发表于 2023-06-23 14:17

觉得难就对了。好好学,以后学别的就轻松了。
一年明月
是的英文部分都是TA写的。因为作业里面就是用double pointer。我到现在也不理解为啥single pointer不够用?TA是这么解释的,我还是不懂,然后还要在callback里面把*ctx重置为NULL?可是pass 给call back的是**ctx,为啥要*ctx =NULL.
majiaamajia 发表于 2023-06-23 16:08

可能这么理解会比较简单:当你malloc时,系统会给你一块memory M,其地址存在一个single pointer中。假如你有一个多线程的程序,不同的线程都需要存取M中的数据,那么一个最简单的办法是大家都记住M的地址(single pointer),存取的时候就用 m->x来取用这些数据。在这种情况下你无法知道M的free事件。假如一个线程free了M,其它线程仍然拥有M活着时的地址,且完全不知道M已经死了。后来如果它们去存取M中的数据,这个旧地址对应的memory很可能已经被系统收回后又malloc给下家了,读到的数据是脏的,如果它写入M,写入的数据对于下家来说肯定也是脏的,程序这时候的行为就会变得无法预测。
假如你使用二级指针,那么所有的线程记住的会是指向M的single pointer (MP)的地址(这里必须保证存放MP的变量寿命严格长于所有这些线程使用MP的寿命)。这时假如其中一个线程free了M,它可以同时说:*MP = NULL. 这样的话,所有其它线程在试图使用M时都会发现它已经死了: if (*MP == NULL) { // don't access M, it's already dead } else { *MP->x .... // access M } 这就避免了之前的混乱场景,估计也是你们TA想要说的:不要随便乱copy指针因为你不知道它们什么时候会死(除非你的程序对于每片memory的ownership和life span都界定得非常清楚)。
但是话说回来,对于多线程的程序来说仅仅保护M的死亡事件是完全不够的。你还需要保护对M的存取事件。比如假设M里存了x和y的存款数额(一人一百),然后线程1让x转了10块钱给y: if (m->x >= 10) { <1> m->x -= 10; m->y += 10; } 但是在线程1在刚要执行<1>的时候忽然被换出去了,线程2进来让x取了100块钱: if (m->x >= 100) { m->x -= 100; } 然后线程1重新登场,从<1>开始执行:现在m->x就是负的了。总之被多个线程使用的数据一般需要更强的保护。



千渔千寻
另外我还有一个问题, 有一个结构体二级指针A,然后这个结构体里面还包含有另一个结构体的二级指针B。 为什么我已经malloc 完A了,我还必须再malloc一下B呢?难道分配给A的内存空间不包括B的内存空间吗?
majiaamajia 发表于 2023-06-23 15:21

在C语言里面,凡是malloc申请分配的内存段,都需要用完用free去释放。
结构体的指针,也是一段空间的起始地址。你这个类似链表结构,实际上是2个内存段,必须/malloc/free 2次。
g
gokgs
可能这么理解会比较简单:当你malloc时,系统会给你一块memory M,其地址存在一个single pointer中。假如你有一个多线程的程序,不同的线程都需要存取M中的数据,那么一个最简单的办法是大家都记住M的地址(single pointer),存取的时候就用 m->x来取用这些数据。在这种情况下你无法知道M的free事件。假如一个线程free了M,其它线程仍然拥有M活着时的地址,且完全不知道M已经死了。后来如果它们去存取M中的数据,这个旧地址对应的memory很可能已经被系统收回后又malloc给下家了,读到的数据是脏的,如果它写入M,写入的数据对于下家来说肯定也是脏的,程序这时候的行为就会变得无法预测。
假如你使用二级指针,那么所有的线程记住的会是指向M的single pointer (MP)的地址(这里必须保证存放MP的变量寿命严格长于所有这些线程使用MP的寿命)。这时假如其中一个线程free了M,它可以同时说:*MP = NULL. 这样的话,所有其它线程在试图使用M时都会发现它已经死了: if (*MP == NULL) { // don''t access M, it''s already dead } else { *MP->x .... // access M } 这就避免了之前的混乱场景,估计也是你们TA想要说的:不要随便乱copy指针因为你不知道它们什么时候会死(除非你的程序对于每片memory的ownership和life span都界定得非常清楚)。
但是话说回来,对于多线程的程序来说仅仅保护M的死亡事件是完全不够的。你还需要保护对M的存取事件。比如假设M里存了x和y的存款数额(一人一百),然后线程1让x转了10块钱给y: if (m->x >= 10) { <1> m->x -= 10; m->y += 10; } 但是在线程1在刚要执行<1>的时候忽然被换出去了,线程2进来让x取了100块钱: if (m->x >= 100) { m->x -= 100; } 然后线程1重新登场,从<1>开始执行:现在m->x就是负的了。总之被多个线程使用的数据一般需要更强的保护。




一年明月 发表于 2023-06-24 16:36

这个不靠谱。
多线程一般要加lock, 跟多重指针没什么关系。
g
gokgs
Argc Argv. Argv 就是最典型的 两层指针的例子。
Tree linked list 理论上也是 N 层指针。普通都是先 dereference 就是了。

一年明月
这个不靠谱。
多线程一般要加lock, 跟多重指针没什么关系。
gokgs 发表于 2023-06-25 19:26

确实是两个独立的问题,但是free事件从本质上说也是对数据的操作,同样需要lock的保护。一般来说如果没有明确固定的ownership和life span,就需要做reference counting了。多线程系统里随便一个线程就可以free,真的太随便了,到时候死都不知道怎么死的。😂
比如一个线程正在热火朝天地存取M里的东西,另一个随手把它free了,这样好吗…… 用两重指针也会segmentation fault。 你的lock如果放在M里面就不能保护free事件。放在外面,你还得管理此lock的life span,楼主的描述显然没有提到啊。
w
wdong
回复 1楼majiaamajia的帖子
与其想乱七八糟的路子,还不如下点功夫把c语言学会了。c语言不管在理工科哪个专业,都算不了一个难的东西。
千渔千寻
回复 89楼一年明月的帖子
free本身是线程安全的。高端一些的mcu里面free也是支持线程安全的。
j
jangreen
学习了