Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!thunder.mcrcim.mcgill.edu!snorkelwacker.mit.edu!think.com!spool2.mu.edu!sdd.hp.com!wuarchive!udel!haven!adm!smoke!gwyn From: gwyn@smoke.brl.mil (Doug Gwyn) Newsgroups: comp.lang.c Subject: Re: Memory allocation/deallocation for tree? Any good way? Message-ID: <14814@smoke.brl.mil> Date: 10 Jan 91 21:05:24 GMT References: <14805@smoke.brl.mil> <20872:Jan1017:54:3891@kramden.acf.nyu.edu> Organization: U.S. Army Ballistic Research Laboratory, APG, MD. Lines: 40 In article <20872:Jan1017:54:3891@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >In article <14805@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: >> In article mcdaniel@adi.com (Tim McDaniel) writes: >> >A free() that did nothing would satisfy ANSI C, ... >> Not strictly true, as the standard specifies that the storage is made >> available for subsequent allocation. However, there is no strictly >> conforming way to test for this behavior. >Doesn't as-if kick in here? A conforming program cannot figure out that >a no-op is different from the definition of free(); therefore the no-op >works as if it were a free() satisfying the literal definition; >therefore the no-op is a valid implementation of free(). Where's the >mistake? The mistake is that failure of a strictly-conforming program to detect an error in the implementation does not magically let the implementation off the hook. It is fairly simple to write a strictly-conforming test program that would EVENTUALLY discover this implementation flaw, but there is no guaranteed upper bound on the amount of time that it would take to discover the problem. Indeed, this strikes me as a useful test to add to C compiler validation suites: while not guaranteeing that any such deficient implementation would be detected, it could at least loop the test enough times to be fairly sure of detecting such a problem in most common environments. For example: #include /* for fprintf, stderr */ #include /* for exit, EXIT_*, free, malloc, size_t */ #define ALLOCS 100000L #define SIZE ((size_t)10000) int main(void) { register void *p; register long n; for (n = 0; n < ALLOCS; ++n) { if ((p = malloc(SIZE)) == NULL) { fprintf(stderr, "FAILED on iteration %ld\n", n); exit(EXIT_FAILURE); } free(p); } return EXIT_SUCCESS; }