BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #74091同步于 2013/9/30
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

为一个指针用malloc分配两次内存会怎样???

xiu062458
2013/9/30镜像同步21 回复
由于我定义了一个全局的结构变量,经常需要给该变量赋值,所以自己对malloc做了个测试。 测试代码如下: #include "stdio.h" #include "conio.h" #include "stdlib.h" main() { char* str=NULL; str=(char *)malloc(sizeof(char)*5); str="hope"; printf("str=%s\n",str); printf("strlen(str)=%d\n",strlen(str)); str=(char *)malloc(sizeof(char)*3); str="li"; printf("str=%s\n",str); printf("strlen(str)=%d\n",strlen(str)); str=(char *)malloc(sizeof(char)*10); str="If you try"; printf("str=%s\n",str); printf("strlen(str)=%d\n",strlen(str)); getch(); } 测试结果如下: str=hope strlen(str)=4 str=li strlen(str)=2 str=If you try strlen(str)=10 问题如下: 如果为一个指针连续分配内存时,上一次分配的内存释放了吗? 上述代码的写法是否合理呢? 我这样做是否会造成内存泄露呢?
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
gsl2011机器人#1 · 2013/9/30
内存泄漏了, 之前分配的已经没法释放掉了。
xiu062458机器人#2 · 2013/9/30
【 在 gsl2011 的大作中提到: 】 : 内存泄漏了, 之前分配的已经没法释放掉了。 请问那怎么办呢?
nuanyangyang机器人#3 · 2013/9/30
【 在 xiu062458 的大作中提到: 】 : : 请问那怎么办呢? 1. C语言的话,只能自己记得free了。或者用别的内存分配方法,比如静态分配。或者自己写一个内存分配器,用malloc分配大块的内存,自己再细分。但总之自己必须知道什么时候分配什么时候回收。既然是C程序员,就有责任管理内存。 2. C++的话,RAII原则:每个资源(包括内存)有唯一的“主人”。一个对象创建的时候分配它拥有的资源,析构的时候释放资源。 3. 换用有垃圾回收的语言吧,比如LISP(这语言的历史比C还长,50年代就开始有垃圾回收了), ML, Haskell, Perl, Python, Java, Ruby, C#, Go ... 4. 用C和C++,同时使用BoehmGC垃圾回收器。这是个“保守”的垃圾回收器,即:因为C语言不知道一个对象的哪一部分是指针,所以BoehmGC必须假定对象的每个域都是指针。保守GC有可能不会及时回收一些垃圾,但保证不会出现无效的指针,而且如果对象内容被清0,它指向的对象是会回收的。最大的优势是用法很简单:把malloc全部换成GC_MALLOC,忘掉free,就行了。 5. 用C和C++,同时自己写垃圾回收算法。比如GTK+的GObject系统用引用计数。但是这是不完整的引用计数,因为无法回收循环垃圾。你可以实现Tracing,也可以实现“准确”(非保守)的GC。但可能用起来会很麻烦。
xiu062458机器人#4 · 2013/9/30
【 在 nuanyangyang 的大作中提到: 】 : : 1. C语言的话,只能自己记得free了。或者用别的内存分配方法,比如静态分配。或者自己写一个内存分配器,用malloc分配大块的内存,自己再细分。但总之自己必须知道什么时候分配什么时候回收。既然是C程序员,就有责任管理内存。 : 2. C++的话,RAII原则:每个资源(包括内存)有唯一的“主人”。一个对象创建的时候分配它拥有的资源,析构的时候释放资源。 : ................... 果然是大神级别的回复,这么详细。 可是问题出现了: 暂且脱离开写的测试代码,我的主要目的是希望对一个全局的结构变量经常性的赋值。 我定义了一个全局的结构变量,形式如下: typedef struct name{ char *first; char *last; }student; 本来,我是想用free来释放空间的,可是free后这个结构变量不就不存在了吗? 所以,每次对其赋值时,我进行深拷贝,以改变结构变量的值。可是结构里有指针,所以每次我都为这些指针分配了空间。 此问题怎么解呢?
nuanyangyang机器人#5 · 2013/9/30
这种一个对象引用另一个对象的情况是最麻烦的。这种情况建议还是换有垃圾回收的语言吧。 否则的话,你要想好first和last指向的对象的“主人”是谁。也就是想好: 1. 谁来分配first和last指向的字符串的内存。 2. 谁来回收这两个内存。 如果student本身不是主人,那就有别的部分负责这些内存的管理; 如果student是主人,还要分几种情况: 1. student要分配first和last的内存。也要回收它们 2. 内存会由别的地方创建,由student回收。这种情况要格外小心,不要让别的代码不小心把内存回收了,而student还留着悬垂引用。
tonyjansan机器人#6 · 2013/9/30
方法一:变成连续空间 // #define MAX_LENGTH 256 typedef struct name{ char first[MAX_LENGTH]; char last[MAX_LENGTH]; } student; void func() { student* p = (student*)malloc(sizeof(student)); free(p); } 优点:一次malloc,一次free,代码简洁明了;缺点:成员长度固定,不能扩展,而且内存浪费很严重。 方法二:自己维护数据结构的alloc,free // typedef struct name{ char *first; char *last; } student, *student_pointer; student_pointer create_student(char* f, int fc, char* l, int lc) { int first_count = (fc > strlen(f))? fc : strlen(f); int last_count = (lc > strlen(l))? lc : strlen(l); student_pointer p = (student_pointer)malloc(sizeof(student) + first_count + last_count); p->first = (char*)p + sizeof(student); strcpy(p->first, f); p->last = p->first + first_count; strcpy(p->last, l); } void delete_student(student_pointer p) { free(p); } void func() { student_pointer p = create_student("Tony", 10, "Jansan", 10); printf("First Name: %s\nLast Name: %s\n", p->first, p->last); delete_student(p); } 优点:一次malloc,一次free,内存长度可自行调节;缺点:需要自己维护内存结构。 【 在 xiu062458 的大作中提到: 】 : : 果然是大神级别的回复,这么详细。 : 可是问题出现了: : ...................
iFadeToBlack机器人#7 · 2013/9/30
你一定要用C来写吗?不能用C++?(不能用string?) 如果以上问题回答都是是的话,用strdup,不然用C++ 另外,即使是用C也有string库可用,人生苦短别不用轮子了
iliketour机器人#8 · 2013/9/30
只要是你申请的空间 在释放前必须你管理,每个malloc返还地址必须自己记住 自己释放 你搞个链表不就解决了
fentoyal机器人#9 · 2013/10/1
【 在 xiu062458 的大作中提到: 】 : : 请问那怎么办呢? 最简单安全直接的做法就是不管--如果你的程序不是要运行20年的那种,也不是狂吃内存吃到操作系统穷的地步,那就不用管它,让你程序自动跑完后,操作系统自动回收所有内存就好了,这个不可能有泄漏。