Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

seg fault when passing f77 string to C

Status
Not open for further replies.

ielo

Programmer
Jan 22, 2004
15
0
0
CA
Sorry if this has been addressed in previous posts - I quickly searched, but couldn't fin and answer ...

I'm statically linking a C library to existing fortran77 code. I need to pass, from a higher-level C function, a f77 string to copy over to the C side. I've written this function that accepts as arguments:
1. a native f77 string
2. the address of a pointer (previously NULLed) to a C string (to fill in)
3. the 'lnblnk' of the original f77 string (i.e. the position of the last non-blank character = strlen)
4. error flagging and messaging variables

--
int AddNull( char* f77string, char** cstring, int f77length, int* eflg, char* emsg )
/*
objective : make C copy of native f77 string, replace first blank character
after last non-blank character (starting from the end) with NULL
requirements : f77string, native f77 character string
cstring, C copy
f77length, defined string length in f77
eflg, error handle
emsg, error message
FAIL, YUP, NOPE
input : f77string, cstring, f77length, eflg, emsg
constants : FAIL, YUP, NOPE (defined in std_constants.h)
globals : none
output : if successful, position of NULL character within string [0 to ~]; else, return 0
side effects : if assumptions OK, cstring is dynamically allocated and NULL terminated, else eflg = YUP
if string does not contain at least one blank character, one will be added at cstring[f77length+1]
assumptions : f77length > 0; cstring == NULL
*/
{
int i, answer, found, size;
char* temp = NULL;
char* string = NULL;

found = NOPE;
answer = 0;

*eflg = NOPE;

if( f77length > 0 && *cstring == NULL )
{
// assumptions OK
size = f77length + 1;
temp = malloc( sizeof( char ) * size );
string = malloc( sizeof( char ) * size );
if( temp != NULL && string != NULL )
{
// memory allocation OK
i = size - 2;
while( i >= 0 )
{
if( i == 0 && found == NOPE )
{
temp = '\0';
answer = i;
}
else
{
temp = f77string;
if( found == NOPE )
{
found = YUP;
temp[i+1] = '\0';
answer = i + 1;
}
}
i--;
}

/* string may have leading blank chars - to eliminate */
while( temp[0] == ' ' )
{
strcpy( string, temp + 1 );
strcpy( temp, string );
}
}
else
{
*eflg = YUP;
strcpy( emsg, "AddNull failed: insufficient memory\n" );
}
}
else
{
*eflg = YUP;
strcpy( emsg, "AddNull failed: invalid input\n" );
}

*cstring = temp;
temp = NULL;
string = NULL;
return answer;
}
--

If I actually printf the content of *cstring before exiting the function, it works fine, but for certain strings, it segfaults when exiting the function. I'm not sure how to proceed from here - any suggestions? Many thanks.
 
> temp = malloc( sizeof( char ) * size );
This never gets freed, so it is a memory leak.

> strcpy( emsg, "AddNull failed: invalid input\n" );
Is emsg actually pointing to sufficient valid memory?

Are you calling this directly from f77 or from another C function?

Please use the [code][/code] tags.


--
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
 
Which compilers/operating systems are you using? The parameter passing conventions could vary.
 
Thanks very much for the replies,

To first respond to the second reply, this is to run on different 'NIX machines, using gcc3.X. Mostly tested on LInux, but there are a few Cygwin users. This is used for 1 to 5 minute simulations of building thermal response. The main f77 program dates back to the late 1970s (although well maintained), with subsequent C functionality added since.

Code:
strcpy( emsg, "AddNull failed: invalid input\n" );
"Is emsg actually pointing to sufficient valid memory?"

Yes!

"Are you calling this directly from f77 or from another C function?"

The function above is called from another C function, which is an intermediate between this - problematic - C function and the main f77 program. The intermediate C function does not manipulate the original fortran string and its 'lnblnk' (i.e. f77string + f77length). It does however instantiate the cstring to be dynamically allocated.

Code:
temp = malloc( sizeof( char ) * size );
"This never gets freed, so it is a memory leak"

If the C cstring inherits the allocated memory to temp (as seen near the end of the function), can I subsequently free the cstring in the intermediate parent function - where it's initiated - which would avoid memory leaks)? I'm assuming so, but if this isn't the case, then I will completely revisit this and work with static strings.

Many thanks in advance!
 
My bad - temp is preserved for later with this
[tt] *cstring = temp;[/tt]
it's string which leaks away with
[tt] string = NULL;[/tt]

> but for certain strings, it segfaults when exiting the function.
Is it always the same string(s)?
Have you run it in the debugger and attempted to work back from the segfault to identify the problem?

One common feature of segfaults is that the cause is often somewhere else in the code, and all you're observing is an effect.

--
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
 
it's string which leaks away with"
Code:
string = NULL;

true - that should be free'ed! Thanks!

"but for certain strings, it segfaults when exiting the function."
Is it always the same string(s)? Have you run it in the debugger and attempted to work back from the segfault to identify the problem? One common feature of segfaults is that the cause is often somewhere else in the code, and all you're observing is an effect."

To keep the post as unlittered as possible, I've deleted a swarm of on-screen prints (i.e .printf) that show me that the segfault oocurs when exiting the function (i.e. it will print out an OK message just before the 'return', but I'm unable to print out a success message on the intermediate parent C-function-side.

It works - or not - with various strings - short strings, long strings. It seems quite random. However, the strings that don't work, never work - strings that do, always do.

"If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut."

I have socks.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top