returning strings in functions

Programming, for all ages and all languages.
Post Reply
stonedzealot

returning strings in functions

Post 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?
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:returning strings in functions

Post by distantvoices »

Could you post the code of your setstring()-function?

Maybe after on, I could do some errortracking.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
stonedzealot

Re:returning strings in functions

Post 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...
stonedzealot

Re:returning strings in functions

Post 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.
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:returning strings in functions

Post 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?
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:returning strings in functions

Post 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.
stonedzealot

Re:returning strings in functions

Post 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)
ark

Re:returning strings in functions

Post 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.
Schol-R-LEA

Re:returning strings in functions

Post 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.
stonedzealot

Re:returning strings in functions

Post 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?
Schol-R-LEA

Re:returning strings in functions

Post 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.
Schol-R-LEA

Re:returning strings in functions

Post 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.
Post Reply