user-0 提问: 关于动态内存的分配与释放

回复:
user: user-1
content: 引用 49 楼 zhao4zhong1 的回复:[quote=引用 48 楼 arthuryangsh 的回复:] [quote=引用 35 楼 wenbo228228 的回复:] 听说OpenGL写的很混，不如3Dmax,有木有写3D游戏的同志，你们用什么写的 3Dmax是用来建模的吧？ 3D编程其实只有OpenGL和Direct3D两种选择。[/quote] Android和iOS上3D编程用啥呢？[/quote] OpenGL及其兄弟们

user: user-0
content: 第一个free释放了，你怎么知道第二个free执行了？段错误是什么？麻烦解释下

user: user-1
content: 引用 49 楼 zhao4zhong1 的回复:[quote=引用 48 楼 arthuryangsh 的回复:] [quote=引用 35 楼 wenbo228228 的回复:] 听说OpenGL写的很混，不如3Dmax,有木有写3D游戏的同志，你们用什么写的 3Dmax是用来建模的吧？ 3D编程其实只有OpenGL和Direct3D两种选择。[/quote] Android和iOS上3D编程用啥呢？[/quote] 仍然是OpenGL

user: user-2
content: 引用 47 楼 wenbo228228 的回复:[quote=引用 37 楼 nadleeh123 的回复:] [quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote]  被释放了还能访问吗？我觉得不可以吧[/quote] 如果释放后就不能访问: char *p = malloc（100）； free(p); free(p); 第二个free就不能够重复释放了，而不是段错误

user: user-3
content: 引用 48 楼 arthuryangsh 的回复:[quote=引用 35 楼 wenbo228228 的回复:] 听说OpenGL写的很混，不如3Dmax,有木有写3D游戏的同志，你们用什么写的 3Dmax是用来建模的吧？ 3D编程其实只有OpenGL和Direct3D两种选择。[/quote] Android和iOS上3D编程用啥呢？

user: user-0
content: 引用 50 楼 nadleeh123 的回复:[quote=引用 47 楼 wenbo228228 的回复:] [quote=引用 37 楼 nadleeh123 的回复:] [quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote]  被释放了还能访问吗？我觉得不可以吧[/quote] 如果释放后就不能访问: char *p = malloc（100）； free(p); free(p); 第二个free就不能够重复释放了，而不是段错误[/quote]  第一个释放后，你怎么知道第二个释放语句是否执行成功了？

user: user-3
content: 引用 51 楼 arthuryangsh 的回复:[quote=引用 49 楼 zhao4zhong1 的回复:] [quote=引用 48 楼 arthuryangsh 的回复:] [quote=引用 35 楼 wenbo228228 的回复:] 听说OpenGL写的很混，不如3Dmax,有木有写3D游戏的同志，你们用什么写的 3Dmax是用来建模的吧？ 3D编程其实只有OpenGL和Direct3D两种选择。[/quote] Android和iOS上3D编程用啥呢？[/quote] 仍然是OpenGL[/quote] 哦。 那Direct3D不能用了吧。

user: user-1
content: 引用 35 楼 wenbo228228 的回复:听说OpenGL写的很混，不如3Dmax,有木有写3D游戏的同志，你们用什么写的 3Dmax是用来建模的吧？ 3D编程其实只有OpenGL和Direct3D两种选择。

user: user-0
content: 引用 37 楼 nadleeh123 的回复:[quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote]  被释放了还能访问吗？我觉得不可以吧

user: user-2
content: 引用 41 楼 user-8 的回复:[quote=引用 40 楼 nadleeh123 的回复:] [quote=引用 39 楼 user-8 的回复:] [quote=引用 37 楼 nadleeh123 的回复:] [quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote] 这个确实不一定，因为释放后，它的映射的物理内存不一定解除映射，只是将这块内存块置为free（可被再次使用），这块内存里面的数据可能还在；[/quote] system up，内存管理单元完成初始化后，所有的内存就在os的监管下，不知道你从哪里学到了的物理内存会在使用后解除映射这种观点。[/quote] 在linux C下，分配堆内存机制就是这样，如果程序一次申请的堆内存过多，使用完后，是不是要解除一部分的物理内存映射，留下几页的物理内存映射？[/quote] 看来你对内存映射理解有点偏差，你所说是堆内存分配只是在分页表里面建立相应数据结构，用完free后删除数据结构，表明相关页处于空闲状态  引用 41 楼 user-8 的回复:[quote=引用 40 楼 nadleeh123 的回复:] [quote=引用 39 楼 user-8 的回复:] [quote=引用 37 楼 nadleeh123 的回复:] [quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote] 这个确实不一定，因为释放后，它的映射的物理内存不一定解除映射，只是将这块内存块置为free（可被再次使用），这块内存里面的数据可能还在；[/quote] system up，内存管理单元完成初始化后，所有的内存就在os的监管下，不知道你从哪里学到了的物理内存会在使用后解除映射这种观点。[/quote] 在linux C下，分配堆内存机制就是这样，如果程序一次申请的堆内存过多，使用完后，是不是要解除一部分的物理内存映射，留下几页的物理内存映射？[/quote]  你所说的这个过程并不是物理地址到虚拟地址的转化，只是维护mmu的页表数据结构罢了，如果free之后就解除了内存映射，那么 char *p = malloc（100）； free（p）； *p = xxx; 这种情况根本就不会出现野指针，第3行就不会被执行，因为会直接段错误。 MMU是个很复杂的玩意儿，以至于powerpc 的某版架构还专门设计了一个硬件机构来加速虚拟地址到物理地址的转化，os启动后物理地址到虚拟地址的映射不会像malloc-free那样频繁去变动，因为维护起来很麻烦，也耗时。

user: user-4
content: The free() function deallocates the space pointed to by ptr, freeing it up for future use. ptr must have been used in a previous call to malloc(), calloc(), or realloc(). free（）函数只能释放由以上几个函数分配的内存，以上几个函数分配的内存在堆中，而你程序中的变量p不在堆而在栈中，所以free()不能释放p。

user: user-5
content: 使用free(q);意图释放指针p的内存，但指针p不是通过malloc在堆中申请的动态内存，而是和普通的类型 如 int i一样存放在栈里，当调用free时，是无法在堆中查询到，也就无从释放  而且在C++中，就算内存被释放了，也就是变成野指针了，有时也是可以使用的，不过出现的结果是不可预知的，如果此时没有对被释放的内存进行过写操作，使用的结果也可能是正确的。即这个内存地址你已经不使用了，但别人不知道还跑来用，但里面的内容没有发生改变，此时别人也能当正常的使用一下。

user: user-2
content: 引用 39 楼 user-8 的回复:[quote=引用 37 楼 nadleeh123 的回复:] [quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote] 这个确实不一定，因为释放后，它的映射的物理内存不一定解除映射，只是将这块内存块置为free（可被再次使用），这块内存里面的数据可能还在；[/quote]  system up，内存管理单元完成初始化后，所有的内存就在os的监管下，不知道你从哪里学到了的物理内存会在使用后解除映射这种观点。

user: user-6
content: 引用 楼主 wenbo228228 的回复:#include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  （1）free错误，应该free(*p)； （2）free（p），p根本没有分配空间，里面只有一个地址

user: user-7
content: 在Linux 中  程序运行  第一次申请 栈内存  会映射33页   内存   也就是 4096*33 个字节 ， malloc底层实现了一个链表 管理着 这些映射的内存  当33页使用满了   会再次映射1页 或者多页 （N*4096  >= 你申请的内存） free只是标示一下这块空间不使用了，如果这块内存正处于 解除映射的物理空间内    再次访问此地址 会出现 段错误     如果这块映射空间没有被解除映射 ，数据也就存在，所以可以访问得到   ，建议不要这样使用

user: user-8
content: 引用 40 楼 nadleeh123 的回复:[quote=引用 39 楼 user-8 的回复:] [quote=引用 37 楼 nadleeh123 的回复:] [quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote] 这个确实不一定，因为释放后，它的映射的物理内存不一定解除映射，只是将这块内存块置为free（可被再次使用），这块内存里面的数据可能还在；[/quote] system up，内存管理单元完成初始化后，所有的内存就在os的监管下，不知道你从哪里学到了的物理内存会在使用后解除映射这种观点。[/quote] 在linux C下，分配堆内存机制就是这样，如果程序一次申请的堆内存过多，使用完后，是不是要解除一部分的物理内存映射，留下几页的物理内存映射？

user: user-3
content: 引用 28 楼 wenbo228228 的回复:问个题外话，我想写个fps（第一人称射击游戏），类似cf,当然不可能像cf那么复杂，只是简单的有一张地图，可以连接玩家在里面游戏，需要学习那些知识，我现在只会c语言基础 搜网络教程“学OpenGL编3D游戏”。

user: user-8
content: 引用 37 楼 nadleeh123 的回复:[quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote] 这个确实不一定，因为释放后，它的映射的物理内存不一定解除映射，只是将这块内存块置为free（可被再次使用），这块内存里面的数据可能还在；

user: user-8
content: 引用 34 楼 wenbo228228 的回复:[quote=引用 32 楼 user-8 的回复:] int i=5;   //这个i是在栈中的，（32位系统下，它占用四个字节），这个i在栈中也是有地址的，这个地址值也是也是四个字节； int * p=&i;  //定义一个int指针变量，这个指针变量也是占用4个字节（32位系统下），这四个字节里面存的是i变量的地址（四个字节），计算机内部变量的地址是指变量的低位字节的地址值，可以这么说，i的低位第一字节的地址和p指针变量里面存放的地址值是一样的；  也就是说，p这个指针变量,它4个字节的空间总共32个01代码，比如说00000000 01100000 00001111 11011101，存放的是i这个整形变量第一个字节在内存中的地址编号，我说的对吗?[/quote] 当你nt *p=&i时，在编译时，p指针变量里面被填充成i变量的地址； 你把变量i的四个字节看成一个整体，i的地址就是它第一个字节的地址； 就是这样的，如果想深入了解这方面，看看汇编知识。。

user: user-2
content: 引用 楼主 wenbo228228 的回复:#include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了