Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!iuvax!cica!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!lavaca.uh.edu!uhnix1!sugar!ficc!peter From: peter@ficc.ferranti.com (Peter da Silva) Newsgroups: comp.lang.c Subject: Re: free (NULL) Message-ID: <1:Y3-L4@xds13.ferranti.com> Date: 6 Jun 90 21:33:52 GMT References: <1771@mindlink.UUCP> <2574@skye.ed.ac.uk> <1074:May3000:24:1990@stealth.acf.nyu.edu> <3102@goanna.cs.rmit.oz.au> <3466:May3022:56:1890@stealth> <9YT3MP@xds13> <270:Jun113:33:1590@stealth> <17486:Jun611:18:1690@ Reply-To: peter@ficc.ferranti.com (Peter da Silva) Organization: Xenix Support, FICC Lines: 59 In article <17486:Jun611:18:1690@stealth.acf.nyu.edu> brnstnd@stealth.acf.nyu.edu (Dan Bernstein) writes: > C'mon, Peter, this is the third time you've just left out the third part > of my paragraph. Perhaps I misunderstood what you were talking about, but it didn't seem to contain any useful information. You have certainly missed *my* point... > It's perfectly fine to keep allocated memory around > between calls, and even pass up a pointer to that memory, *provided* > that the pointer isn't *defined* by your interface as a pointer to > *allocated* memory. In other words, you must provide an unreadline() to > free the memory. That's what I don't agree with. It's perfectly fine to have a routine return malloc-ed memory, so long as it's defined as returning allocated memory. You're saying that you need to have an explicit destructor matching any constructor. It may be desirable to do this for certain interfaces, but making it a hard and fast rule that you have to do this makes about as much sense as banning functions with side effects. [ in question: strdup(s) char *s; { char *t = malloc(strlen(s)+1); if(t) strcpy(t, s); return t; } ] > This is a mistake, because the pointer is *defined* by the interface as > a pointer to *allocated* memory. Either the parent should malloc() and > strcpy(), or strdup() should also have an unstrdup() to free the memory. Not at all. If you have code that's full of: if(foocopy = malloc(strlen(foo)+1)) strcpy(foocopy, foo); Why not declutter your code with: foocopy = strdup(foo); Yes, you can clutter things up again with strfree(), but now you have to treat strings allocated with strdup differently from strings explicitly malloced (say with: if(buf = malloc(strlen(path) + strlen(fname) + 2)) sprintf(buf, "%s/%s", path, fname); or the equivalent), and so on. And are you going to require that none of these new objects are ever returned from another function? > To put it differently: Never, ever, ever pass internally malloc()ed > memory up to your parent (this is what I said)---but, as always in C, > feel free to apply the as-if rule. To put it differently: it's usually a good idea to build creator/destructor functions for objects, but there is no need to make it a hard and fast rule. And I don't think Boyd said anything differently. -- `-_-' Peter da Silva. +1 713 274 5180. 'U` Have you hugged your wolf today? @FIN Dirty words: Zhghnyyl erphefvir vayvar shapgvbaf.