Unix Programming - Why the SEGFAULT in this code?

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > September 2004 > Why the SEGFAULT in this code?





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Why the SEGFAULT in this code?
RJGraham

2004-09-22, 9:21 pm

Can someone tell me why the code below should segfault at the line
indicated?

Also, why does strtok_r() require a **ptrptr and not a *ptr?
(Maybe this is a clue to my problem and misunderstanding of how strtok_r
is used...).

Thanks for any insight.

-Randy

PS: str arg is always guaranteed to point to a valid string < 127 chars


void getNameValuePairFromString(char * str, string & name, string & value)
{
char * buf = (char *) malloc(128);
char * tok = strtok_r(str, " =\n\r", &buf);
if (tok != NULL)
{
name = tok;
tok = strtok_r(NULL, " =\n\r", &buf);
if (tok != NULL)
value = tok;
}
free(buf); // seg fault here !!!
}
Rich Gibbs

2004-09-22, 9:21 pm

M=E5ns Rullg=E5rd said the following, on 09/17/04 19:39:
> RJGraham <null@null.com> writes:
>=20
>=20

In addition to what M=E5ns has told you, you also need to insert here:

#include <stdlib.h>[vbcol=seagreen]
ue)[vbcol=seagreen]
>=20
>=20


And you should not cast the returned value of malloc, but you should=20
check that it is not NULL. The returned value from malloc is of type=20
"pointer to void", which can be converted into any object pointer.

If (because stdlib.h is not #included) there is no prototype in scope=20
for malloc, it is assumed to return 'int' by default. Although it is=20
true on many platforms that you can go between 'int' and pointer types=20
without trouble, it is _not_ always true (and certainly is not=20
guaranteed in standard C). The presence of the cast will usually=20
prevent the compiler from warning you of a potential problem.

> strtok_r modifies the value of buf, hence the need for the double
> pointer. You should save the original value somewhere and pass that
> to free().
>=20
>=20
>=20
>=20



--=20
Rich Gibbs
rgibbs@alumni.princeton.edu

Lev Walkin

2004-09-22, 9:21 pm

Rich Gibbs wrote:
>
> And you should not cast the returned value of malloc, but you should
> check that it is not NULL. The returned value from malloc is of type
> "pointer to void", which can be converted into any object pointer.
>
> If (because stdlib.h is not #included) there is no prototype in scope
> for malloc, it is assumed to return 'int' by default. Although it is
> true on many platforms that you can go between 'int' and pointer types
> without trouble, it is _not_ always true (and certainly is not
> guaranteed in standard C). The presence of the cast will usually
> prevent the compiler from warning you of a potential problem.


That's the common thing written in many books and FAQs describing the C
programming language.

However, it is not quite so in case of C++, because of stricter type checking.
It just doesn't allow assigning uncasted malloc() to types different from
void*.

The compatible approach to make the C source code be compilable as
part of C++ framework is to cast the lvalue:

type_t *ptr;
(void *)ptr = malloc(...);

This would prevent C++ complaints and also preserve the desired
"fail when malloc is not declared" semantics.

--
Lev Walkin
vlm@lionet.info
Måns Rullgård

2004-09-22, 9:21 pm

Lev Walkin <vlm@lionet.info> writes:

> Rich Gibbs wrote:
>
> That's the common thing written in many books and FAQs describing the C
> programming language.
>
> However, it is not quite so in case of C++, because of stricter type
> checking. It just doesn't allow assigning uncasted malloc() to
> types different from void*.
>
> The compatible approach to make the C source code be compilable as
> part of C++ framework is to cast the lvalue:
>
> type_t *ptr;
> (void *)ptr = malloc(...);
>
> This would prevent C++ complaints and also preserve the desired
> "fail when malloc is not declared" semantics.


Using a cast expression as an lvalue is non-standard and doesn't work
with the most recent gcc versions.

--
Måns Rullgård
mru@mru.ath.cx
Floyd L. Davidson

2004-09-22, 9:21 pm

Lev Walkin <vlm@lionet.info> wrote:
>Rich Gibbs wrote:
>
>That's the common thing written in many books and FAQs describing the C
>programming language.
>
>However, it is not quite so in case of C++, because of stricter type checking.
>It just doesn't allow assigning uncasted malloc() to types different from
>void*.
>
>The compatible approach to make the C source code be compilable as
>part of C++ framework is to cast the lvalue:
>
> type_t *ptr;
> (void *)ptr = malloc(...);
>
>This would prevent C++ complaints and also preserve the desired
>"fail when malloc is not declared" semantics.


However, if that was in fact C++ code, there is no reason for using
malloc() to obtain memory space.

Of course, in that particular example, the is no reason to malloc()
space for the pointer in either C or C++! Both the call to malloc()
and free() should be removed.

--
FloydL. Davidson <http://web.newsguy.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska) floyd@barrow.com
RJGraham

2004-09-22, 9:21 pm

"Rich Gibbs" <rgibbs@REMOVEalumni.CAPSprinceton.edu> wrote in message
news:414bb388@news101.his.com...
Måns Rullgård said the following, on 09/17/04 19:39:[vbcol=seagreen]
> RJGraham <null@null.com> writes:
>
>

In addition to what Måns has told you, you also need to insert here:

#include <stdlib.h>[vbcol=seagreen]

FWIW, this is just a code snippet.
#include <stdlib.h> *is* included in the actual source file, sorry I wasn't
clear on this.

-Randy


Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com