C 语言的malloc()
函数分配的是应该算是动态内存还是自动内存?我记得应该是动态内存,只要我没有 free,它就一直存在。但我在 void 函数中初始化一块内存,函数调用结束后这个指针也变成未定义了,难道这里分配的内存作用域只在函数内部吗
1
owenliang 2018-05-27 12:41:49 +08:00 via Android
好的
|
2
zwy100e72 2018-05-27 12:44:54 +08:00 1
你在函数内部调用 malloc 分配内存,但是没有把内存指针保留下来的话,函数退出后这部分内存没有释放,你也无法访问,那么就是内存泄漏了。
任何程序都应当避免内存泄漏。 |
3
adadada 2018-05-27 12:45:15 +08:00 2
第一个问题:动态内存。第二个问题:函数里声明的指针*变量*的作用域在函数体里,但是它指向的内存的不是,你可以把内存的地址返回出来,在函数之外继续用。
|
4
v2exchen 2018-05-27 12:48:16 +08:00 via Android
你是通过什么方式把内存地址返回的,是 return。还是传参的方式,如果是传参的方式需要用指针的指针
|
5
whoami9894 OP |
6
whoami9894 OP @adadada
嗯那就是应该函数设返回值,返回那个指针指向的地址。那函数声明的指针需要显式的 free 吗 |
7
whoami9894 OP @v2exchen
我开始的错误理解是函数中分配的指针应该一直存在,所以函数没有返回值。现在懂了,应该返回分配的地址,函数中的指针不是一直存在 |
8
verrickt 2018-05-27 12:55:02 +08:00 via Android
malloc 分配的内存是在堆上的(进程地址空间的 data 区),需要显示 free
> 但我在 void 函数中初始化一块内存,函数调用结束后这个指针也变成未定义了 没理解你的意思,如果是这样 ``` c int* ub() { int i; return &i } ``` 的话,i 实际是分配在栈上的局部变量,函数返回后栈帧弹出,试图访问&i 的已经是未定义行为(ub)了。 总结来说,搞明白地址在栈上还是堆上就可以判断栈帧回弹之后使用指针是不是 ub 了 |
9
whoami9894 OP @verrickt
```c void get_cc(){ int* poi = (int*) malloc(sizeof(int*)); int ll = 1; poi = ≪ } void main(){ get_cc(); printf("%d",*poi); } ``` 我的意思是这样的,我错误理解 poi 指针会一直保存,但应当是那块地址会保存,poi 随函数销毁 |
10
adadada 2018-05-27 12:58:28 +08:00
@whoami9894 #6 #6 如果没有其它的办法在函数之外释放,那就需要在函数体里 free。
|
11
whoami9894 OP |
12
momocraft 2018-05-27 13:16:49 +08:00
分不分配内存都 "存在", 只是 malloc()之后 free()之前这段时间归你用
|
13
whoami9894 OP |
14
WordTian 2018-05-27 13:34:41 +08:00 via Android
@whoami9894 #9 总结一下,大致就是这样了
int* poi = (int*) malloc(sizeof(int*)); 左边的变量在栈区,get_cc 函数结束后,该函数的栈弹出,变量销毁 malloc 分配的内存在堆区,然后把分配的内存的地址传给栈区的 poi 指针 main 中调用 get_cc 结束后,poi 变量消失,但堆区中分配的内存还在,这时就造成了内存泄漏 |
15
whoami9894 OP @WordTian
对的,感谢 |
17
verrickt 2018-05-27 14:54:18 +08:00
@whoami9894 如果还是不太懂的话,可以看一看 CSAPP 的 Machine-Level Representation of Programs 部分
|
18
whoami9894 OP @verrickt
感谢感谢!您回复的太认真了 |
19
zhicheng 2018-05-27 16:23:04 +08:00
@whoami9894 你 9 楼的代码编译都过不去的,不懂的写个代码实验一下,不要读死书。你不理解的地方是你没有区分开变量和值。
|
20
rosu 2018-05-27 16:37:40 +08:00 via Android
|
21
ipwx 2018-05-27 16:44:09 +08:00
操作系统不会无缘无故把一块物理内存给某个进程,有需要的话,要申请。
但是每次向操作系统都申请太慢了,所以各编程语言其实是一大块一大块地向操作系统申请的。 每次有个小内存的 malloc,编程语言先试图从已经申请但没有用的内存里面切一块给用户程序。如果不够,再向操作系统申请。 而所有已经向操作系统申请的大块内存、以及切分方案,各个编程语言在全局变量空间自行维护。 函数里面的临时内存空间那是栈空间,不归 malloc 和编程语言的这套机制管。 |
22
whoami9894 OP @zhicheng
……那段代码是告诉他我当时理解的错误。贴子主体就说了编译器会报未定义。 |
23
whoami9894 OP @rosu
那段代码局部 int 和指针变量会随函数销毁,我的理解错误是没分清指针和内存,就像楼上说的没区分指针变量和内存的值 |
24
zhicheng 2018-05-27 18:30:40 +08:00
|
25
afpro 2018-05-27 18:31:45 +08:00
这和内存没什么关系吧 明显是楼主还没分清内存和指针的关系
|
26
whoami9894 OP @zhicheng
我用哪种错误方式去理解了? 我最开始是想着定义 void 函数分配一块内存,认为内存会一直存在,这里没分清楚指针和内存,错误认为函数内定义的指针等同于函数内定义的内存一样会一直存在直到 free。说到底不是变量作用域存活周期那些问题,是指针和内存问题 |
27
whoami9894 OP @afpro
你在说哪儿 |
28
zhicheng 2018-05-27 19:00:17 +08:00 via iPhone
@whoami9894 我说了 9 楼的代码是错的呀,如果你觉得那个代码没错,那 You are right.
|
29
whoami9894 OP @zhicheng
我发这个贴子就是因为理解错误所以写出那样的代码,之后你又说我在强行解释,"用另一种错误方法理解"。接着我问你是哪种错误方式,你又兜回 9l,我从没说 9l 是对的吧大哥,就是因为它错了我才来发帖问的。 |
30
zhicheng 2018-05-27 19:12:00 +08:00 via iPhone
@whoami9894 你是对的。
|
31
liuhaotian 2018-05-27 19:16:49 +08:00
@zhicheng #24
@afpro #25 @whoami9894 #22 只有我一个人觉得 9#的代码最大的问题是变量作用域的问题吗 编译器里报的未定义 是 not declared variable,准确来说是 变量未声明 而上面几位说的未定义 ub 是 undefined behavior 似乎楼主认为这两个未定义是同一个东西了 |
32
zhicheng 2018-05-27 19:20:37 +08:00 via iPhone
@liuhaotian 其实我想了一下,觉得他大概看书看到赋值那一章就能搞懂了。
|
33
whoami9894 OP @liuhaotian
对啊,指针变量的作用域只在函数内部。我没分清指针变量和内存,以为**指针**这个变量像**动态内存**一样。就是因为理解有问题.....有点说不清 |
34
OneNian 2018-05-27 19:26:57 +08:00
先把 C 语言基础看完。(加油吧这基础差的有点多)
|
35
OneNian 2018-05-27 19:28:41 +08:00
main 里声明一个指针变量,函数 return 地址。
方法有很多。不急。多看书做题 |
36
pkookp8 2018-05-27 20:45:53 +08:00 via Android
白看了好久。。。9 个字,自己搜吧
局部变量和全局变量 |