home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!cs.utexas.edu!ut-emx!tivoli!shasta!bjv
- From: bjv@shasta.tivoli.com (Brian Vetter)
- Newsgroups: comp.unix.programmer
- Subject: Re: I am stumped by this one!!!
- Message-ID: <2283@tivoli.UUCP>
- Date: 30 Jul 92 18:24:38 GMT
- References: <1992Jul24.204944.18516@cbfsb.cb.att.com> <Brx394.4qL@undergrad.math.waterloo.edu> <13744@auspex-gw.auspex.com> <1992Jul27.134826.5592@cbfsb.cb.att.com>
- Sender: news@tivoli.UUCP
- Distribution: usa
- Organization: TIVOLI Systems
- Lines: 117
-
- In article <1992Jul27.134826.5592@cbfsb.cb.att.com>, rajeev@cbnewsf.cb.att.com (rajeev.dolas) writes:
- |>
- |> I realize the error on sizeof instead of strlen() for malloc. But
- |> I don't think that is the cause of SEGV error. If you look at my
- |> original posting, you will notice that I am able to copy selected
- |> characters to cp_line.
- |>
- |> In my original code I wasn't even using the cp_line. I was reading
- |> a char pointed to by *pbuf and was writing that to the file. I
- |> got the SEGV error on the putc()!!! Now I am using fputs() to
- |> write a string instead of a char and I get the same error on
- |> fputs(). Also fputs(tmp_line,stdout) works fine while
- |> fputs(tmp_line,fp1) does not!!! That's what is driving me nuts.
-
- It looks to me that you have several problems with your code. First,
- the sizeof is a serious problem. If you look at your code, you'll see that
- once you copy more than 4 bytes from the pbuf to cp_line, you will
- start overwriting the data you allocated for cp_line. This can cause
- all kinds of unpredictable errors.
-
- Secondly, after you complete your loop "while (*pbuf != '\0')", you
- never terminate the cp_line string with a NULL character. fputs() would
- continue writing data after the end of your string (potentially many bytes).
-
- The SEGV message you get is in the malloc code. fputs() and all of the
- stdio functions that write using a FILE * may (and frequently do) call
- malloc to keep a buffer so that writes perform better. In general, when
- you get SEGVs and BUSERRs in malloc, it is due to dynamically allocated
- buffers being overwritten. malloc() keeps information about the allocation
- pool mixed in with your allocated data so it is easy to confuse.
-
- The bug you are looking for may not even be in the code you have provided.
- Based on what I can see here, you must be fairly new to C or to some of the
- more common extensions. I would suggest you get a debug version of malloc
- to link against your code or try a commercial product such as Purify.
- They can help you find such problems if you aren't familiar enough debugging
- dynamic memory bashing code.
-
- As a critique of your code:
-
- pars_wbuf[strlen(pars_wbuf)] = '\0' Isn't needed - fgets already put the
- null byte at the end - otherwise the
- strlen would fail.
-
- The sizeof is WRONG and your code WILL FAIL if you don't fix it.
-
- It looks like the else clause just strips out the \r character (CR).
- Why do the malloc at all? Why not just copy the data in place? ie:
-
- for (to=pars_wbuf, from=pars_wbuf; *from; from++) {
- if (*from != '\r') {
- *to++ = *from;
- }
- }
- fputs(pars_wbuf, fp1);
-
- This isn't even optimal since you don't need to do the assignments until
- you find the first CR.
-
- |>
- |> I am including the relevant portion of the code to clarify my
- |> point and not to drive the 2400 baud-ers nuts :-)
- |>
- |> /* str_comp is my function which returns -1 if match is not found */
- |> while((fgets(pars_wbuf, 80, fp2) != NULL) &&
- |> ((parse_ret = str_comp(cmp, pars_wbuf)) != 0))
- |> {
- |> pars_wbuf[strlen(pars_wbuf)] = '\0';
- |> pbuf = pars_wbuf;
- |> cp_line = (char *)malloc(sizeof(strlen(pars_wbuf)));
- |> strcpy(cp_line, "\0");
- |> tmp_line = cp_line;
- |>
- |> if((comp = line_comp(pars_wbuf)) == 0)
- |> ;
- |> else
- |> {
- |> /* Traverse thru pbuf, skip "
- |> while(*pbuf != '\0')
- |> {
- |> if(*pbuf != 0x0D)
- |> {
- |> /* I was writing a char at a time to
- |> the file before. This part works
- |> on Amdahl but not on a sun. */
- |>
- |> /**
- |> ch = *pbuf;
- |> fprintf(stdout, "%c", ch);
- |> if((he = putc(ch, fp1)) < 0)
- |> {
- |> printf("pars_conf: Write error\n");
- |> return(-13);
- |> }
- |> **/
- |>
- |> /* Now I save it to a buffer */
- |> *cp_line++ = *pbuf;
- |> }
- |> *pbuf++;
- |> }
- |> /* If I do a fputs to stdout, it works fine */
- |> /**
- |> fputs(tmp_line, stdout);
- |> fflush(stdout);
- |> **/
- |>
- |> /* dbxtool shows the following error on this instr -
- |> signal SEGV in malloc at 0xf773634
- |> malloc+0x150: st %o0, [%15]
- |> */
- |> fputs(tmp_line, fp1);
- |> }
- |> free(cp_line);
- |> }
- |>
- |> }
-