Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com To: cygwin AT cygwin DOT com X-Injected-Via-Gmane: http://gmane.org/ Path: not-for-mail From: "Max" Newsgroups: gmane.os.cygwin Subject: free() vs realloc() on cygwin Date: Sat, 22 Jun 2002 09:56:28 -0400 Lines: 284 Message-ID: Reply-To: "Max" NNTP-Posting-Host: sdn-ar-001vacharp289.dialsprint.net X-Trace: main.gmane.org 1024755833 14952 168.191.212.155 (22 Jun 2002 14:23:53 GMT) X-Complaints-To: usenet AT main DOT gmane DOT org NNTP-Posting-Date: Sat, 22 Jun 2002 14:23:53 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.00.2615.200 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2615.200 Hi, I ran into an issue that I thought was strange while doing some C development on cygwin 1.3.10 with gcc 2.95.3-5. For one section of code I have, I found that if I used free() to try and free the memory I had asked for with malloc() or calloc(), my program died with signal 11 ... but if I changed the call to use realloc(), the program ran just fine. I tried running the program I am developing on FreeBSD and there were no problems with the free() call on that OS ... Does this sound like a Cygwin quirk or am I just missing something with my C? Here is the code ... newargv(), makeargv(), then freeargv() (Adapted from Practical UNIX Programming) ... Any help appreciated .. and please let me know if I am not posting this to the proper place. Thank you. Max Example usage: char ***argvp = NULL; char *cmd = "ls -al /etc/hosts"; argvp = newargv(); makeargv(cmd, " ", NOTOKENS, argvp); // ... work on argvp freeargv(argvp); ===================== char ***newargv() { char ***ptr = (char ***) malloc(sizeof(char ***)); if (ptr == NULL) perror("ARGV malloc"); return ptr; } void freeargv(char ***argvp, int len) { int i = 0; char *ptr_addr = NULL; debug("freeing argvp"); for (i = (len - 1); i >= 0; i--) { ptr_addr = *((*argvp) + i); debug("Free char * ptr %d s(%s), x(%x)", i, ptr_addr, &ptr_addr); realloc(ptr_addr, 0); <<<<<-- USING free() causes program to die with signal 11 on cygwin! } debug("Free base ptr"); realloc(*argvp, 0); <<<<<-- USING free() causes program to die with signal 11 on cygwin! } /* Make argv array (*argv) for tokens in s which are separated by delimiters. Return -1 on error or the number of tokens otherwise. */ int makeargv(char *s, char *delimiters, int flags, char ***argvp) { char *t; char *snew; int numtokens; int i; /* snew is real start of string after skipping leading delimiters */ snew = s + strspn(s, delimiters); /* create space for a copy of snew in t */ if ((t = calloc(strlen(snew) + 1, sizeof(char))) == NULL) { *argvp = NULL; numtokens = -1; } else { strcpy(t, snew); if (estrtok(t, delimiters, flags) == NULL) { numtokens = 0; } else { for (numtokens = 1; estrtok(NULL, delimiters, flags) != NULL; numtokens++) ; debug("We have %d tokens", numtokens); /* Create an argument array to contain ptrs to tokens */ if ((*argvp = calloc(numtokens + 1, sizeof(char *))) == NULL) { debug("Calloc == NULL"); free(t); numtokens = -1; } else { debug("Calloc != NULL"); if (numtokens > 0) { strcpy(t, snew); **argvp = estrtok(t, delimiters, flags); for (i = 1; i < numtokens + 1; i++) { *((*argvp) + i) = estrtok(NULL, delimiters, flags); } } else { **argvp = NULL; free(t); } } } } return numtokens; } char *estrtok(char *src, const char *delimiters, int flags) { static char **work = NULL; char *tok; if (src != NULL) { if (work != NULL) { free(work); } work = (char **) malloc(sizeof(char **)); if (work == NULL) { perror("Malloc static char ** failed"); return NULL; } } tok = estrtok_r(src, delimiters, flags, work); debug("After estrtok_r: work points at %x (%x)", work, *work); return tok; } char *estrtok_r(char *src, const char *delimiters, int flags, char **lasts) { char *tok = NULL; int i = 0; int length = -1; if (lasts == NULL) { fprintf(stderr, "User supplied char ** NULL!\n"); return NULL; } /* If src is not NULL, clear work area if it is initialized */ if (src != NULL) { *lasts = src; debug("New estrtok, lasts is: %x (%s)", lasts, *lasts); debug("Delimiters: %s", delimiters); } /* Now find the next string portion, starting from current position and moving up the string, checking each character against the delimiters string. If a match is found before the length of the string, find the next delimiter, then return that portion of the string. cur_pos gets set to the position of the ending delimiter. If no match is found, return the whole string and set cur_pos to the size of the string. If cur_pos is at the end of the string, return NULL. */ /* If we are at the end of the string already */ debug("Lasts first char is: %c", *(*lasts)); if (*(*lasts) == '\0') { debug("lasts is null"); return NULL; } for (i = 0; *((*lasts)+i) != '\0'; i++) { debug("Checking %c against %s", *((*lasts)+i), delimiters); if (strchr(delimiters, *((*lasts) + i)) != NULL) { debug("Found delimiter, length is %d", i); length = i; break; } } /* If we reached end of string without finding, end of string is our substring */ if ( *((*lasts)+i) == '\0') { length = i; } /* Now check end and pull out string */ debug("Start is %x, end is %x: ", *lasts, (*lasts)+length); tok = (char *) calloc((length + 1), sizeof(char)); if (tok == NULL) { perror("Calloc tok array failed"); return NULL; } /* Copy string over */ for (i = 0; i < length && *(*lasts) != '\0'; i++) { *(tok+i) = *(*lasts); (*lasts)++; debug(">%c<", *(tok+i)); } (*lasts)++; *(tok + i + 1) = '\0'; debug("This token (from %s): >>%s<<", *lasts, tok); /* If NOTOKENS is on, skip consecutive delimiters */ if (flags == NOTOKENS) { debug("No tokens is on"); while (strchr(delimiters, *(*lasts)) != NULL) { debug("Found %c at %x", *(*lasts), *lasts); (*lasts)++; if (*(*lasts) == '\0') { break; } } } debug("Exiting estrtok function, lasts now points at %c", *(*lasts)); return tok; } -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/