Page 1 of 1

returning strings in functions

Posted: Sat Mar 01, 2003 1:09 pm
by stonedzealot
God, I've been asking so many questions it seems like I'm abusing the boards, I hope some other people benefit from all these questions. Anyway, I can't get functions to return strings. Check this *basic* code out:

Code: Select all

char *returnstring()
{
    char *returnval = 0;
    setstring(returnval, "test");
    return returnval;
}

<--in main function-->
char *teststring
setstring(teststring, returnstring());
Pretty basic, I thought but evidently not, because it thinks that returnstring() gives an integer and thus gives the error "passing arg2 of setstring makes pointer of integer without cast" on the setstring line in the main function. What am I doing wrong?

Re:returning strings in functions

Posted: Sat Mar 01, 2003 1:37 pm
by distantvoices
Could you post the code of your setstring()-function?

Maybe after on, I could do some errortracking.

Re:returning strings in functions

Posted: Sat Mar 01, 2003 1:43 pm
by stonedzealot
Haha, my setstringfunction requires other functions, which require other functions etc. I'll just post up the entire string.c stonedzealot.dynu.com/string.c

I'm hesistant to think that it's anything in here, considering that they're old functions I wrote that have been working for everything else...

Re:returning strings in functions

Posted: Sun Mar 02, 2003 2:16 am
by stonedzealot
I really hate to bump this post (I know it's looked down upon) but this question is absolutely vital...nothing has changed, I've screwed with it all morning and it still doesn't like it.

Re:returning strings in functions

Posted: Sun Mar 02, 2003 3:57 am
by distantvoices
wangpeng, I could not reconstruct the compiler error, neither with linux-gcc nor with windows ms visual c++. Your code is correct, as far as i have evaluated.

Which compiler do you use?

Re:returning strings in functions

Posted: Sun Mar 02, 2003 6:14 am
by Pype.Clicker
its most likely that returnstring() hasn't been declared before it is called in main. Therefore, the compiler assumes that it accepts any number and format of arguments and that it returns int.

While setstring expects a char* , it will cast it, bt issues a warning. Try to put your returnstring() function before your main function or at least to declare its prototype before.

Re:returning strings in functions

Posted: Sun Mar 02, 2003 9:18 am
by stonedzealot
@Pype.Clicker -- Nope, it's defined. Also, I think this is OS related, as I'm doing it without libraries or anything (but that's just MO) ::)

@beyondinfinity -- DJGPP (GCC), btw...did you put the setstring() function above the main() function (like Pype.Clicker suggested in the post after you?

I'll try your suggestions. I'll transfer the thing to my Linux partition and try it withLinux GCC and try putting the returnstring() before the main function. Thanks alot!
(sorry I had to bump)

Re:returning strings in functions

Posted: Sun Mar 02, 2003 12:00 pm
by ark
I can't duplicate the compilation error you're getting in Visual C++, either, although when running the program I did get an illegal operation message resulting from the fact that returnstring passes a null pointer to setstring.

And in the code you provided here, teststring is passed to setstring without being initialized (pointing to a random location in memory)...and there's no semicolon at the end of teststring's declaration.

Re:returning strings in functions

Posted: Sun Mar 02, 2003 12:25 pm
by Schol-R-LEA
I know it's unlikely to be the real cause of the problem, but assuming that the code shown here is the actual running code, then it looks like there is a typo:
[tt]
<--in main function-->
char *teststring <---- no semicolon
setstring(teststring, returnstring());
[/tt]

This would cause the compiler to treat the line as a function prototype,

[tt]char* teststring setstring(teststring, returnstring());[/tt]

That would certainly cause a puzzling compiler error of the sort you describe, and would be hideously hard to spot. A longshot, but I thought I'd bring it up.

(NOTE: If you intentionally skipped the memory management details for this example, then feel free to ignore the rest of this advice. Otherwise, read on.)

In any case, this code shouldn't work at all: the strings aren't getting allocated, so there is no valid memory for setstring() (and hence clearstring(), copychars(), etc.) to work in - it uses the address the pointer is set to, addresss zero, which is probably not what you wanted. The compiler wouldn't complain, as this is a perfectly valid action as far as it is concerned, but it could lead to any number of runtime errors, with data or code overwriting, page faults, and/or segmentation faults being likely.

In the case of main(), you could simply declare a local char array more than large enough to hold the string, like this

Code: Select all

/* part main() */
char buffer[256];
char *teststring = &buffer;
However, this won't work for returnstring(); since local variables are stored in the function's stack frame, which gets deallocated when the function exits, so you'd be stuck with a wild pointer (one which could potentially scribble on the stack).

To get a string you can pass as a return value, you'll need to dynamically allocate the space from the heap. This can be done by getting the length of the source string, use that to allocate the memory for the pointers, then copying the source string to the newly-allocated space. Whether this is done in the calling function or the copy function is up to you, provided that all allocated memory that is eventually deallocated (otherwise it would result in a memory leak). As a possible example (using the stardard memory functions - you'll need to implement your own, of course):

Code: Select all

#include "wpstrings.h"
#include <stdlib.h>

main()
{
char *sourcestring;
char teststring[256];

sourcestring = returnstring();  
/* this pointer has to be captured  so that it can be deallocated later */

setstring(&teststring, sourcestring); 
 /* note the reference operator - teststring is a char array, not a pointer */

free(sourcestring);
printf("%s", teststring);
}

char *returnstring()
{ 
? ? char *returnval = 0;
    char test[] = "test";
   
    returnval = (char *) malloc( (size_t) stringlength(test));
? ? setstring(returnval, test);
? ? return returnval;
}
BTW, this is even more of a problem with your concatstring() function; str1 has to have already allocated space sufficient to hold both strings in advance of the strings being concatenated. It isn't a bug in the function - the standard C function strcat() is nearly identical in behavior - but it does mean you need to take a few extra steps in using it that may not be obvious.

I was curious why you wrote these, rather than implementing the standard c-string functions (strcmp(), strcopy(), etc.). The functionality is very similar, just using different (admittedly less clumsy) names and not returning a value. I assume you have a reason for this, and I was wondering what it was.

EDIT: Added casts to malloc() call, fixed free() call.

Re:returning strings in functions

Posted: Sun Mar 02, 2003 1:19 pm
by stonedzealot
@Joel : No, this isn't a copy of the code, I just typed it in, the semicolon is an error only here.

@Schol-R-Lea: Ouch, a lot of stuff that I ignorantly passed over! As for why I didn't use the standard string libraries...that's simple...I wanted to do it myself ;D but I suppose I should have at least looked at them :-[.

Thanks alot to the both of you, I'll get cracking on the thing write (silly little string pun) now. BTW, do you know where I can get my hands on the source for those functions?

Re:returning strings in functions

Posted: Tue Mar 04, 2003 4:20 pm
by Schol-R-LEA
If you download the full source for the gcc libraries, that should be in with it; however, the gcc code is unusually complicated, largely because of it's use across multiple platform for both C and C++. Keep in mind that string.c, the C string library, is very different from strings.c, which is the C++ String class and the tools for dealing with c-strings in a C++ context.

An easier (though less complete) example can be found at:

http://nemesis.sourceforge.net/browse/n ... ing.c.html

In all honesty, your code would make a good basis for an implementation of the C string library, though it would take quite a bit of additional code and some minor changes to the functions already there, mostly regarding the function parameters and return types. Rewriting a few of them in assembly might be nice, too, though it probably would be of little advantage and would lose the portability of the C code.

Re:returning strings in functions

Posted: Wed Mar 05, 2003 4:16 pm
by Schol-R-LEA
Let me add something: looking at the source distribution that comes with DJGPP, the string library sources are in the subdirectory

[tt]c:\djgpp\src\libc\ansi\strings\[/tt]

(slashes reversed for the Linux users' sake)

Each separate function has it's own source file (either C or assembly). I would expect that under Linux the equivalent path would be

[tt]/usr/src/libc/ansi/strings/[/tt]

but I'm not sure; I'll have to check next time I'm running Linux.