Thread: returning strings - function.

  1. #1
    Registered User Vber's Avatar
    Join Date
    Nov 2002
    Posts
    807

    returning strings - function.

    Hello, I'm trying to "import" the perl function called "join", you can see what this function make's here. Now I have this code:
    Code:
    int join (char str1[], char str2[], char w, char buf[], int size) {
    	int i,j;
    	unsigned long totsz;
    	totsz = sizeof(str1) + sizeof(str2) + sizeof(w);
    
    	//check if space is sufficient
    	if (size <= totsz)
    		return 0;
    
    	for (i=0; str1[i]; i++)
    		buf[i] = str1[i];
    
    	buf[i++] = w;
    	
    	for (j=0; str2[j]; j++,i++)
    		buf[i] = str2[j];
    
    	buf[i] = '\0';
    	return 1;
    }
    
    int main(void) {
    	char buf[1000];
    
    	if ((join ("lala", "lele", ':',buf, sizeof(buf))) != 0)
    		printf("Buf = %s\n",buf);
    	else
    		printf("There was an error, probaly buffer is too small\n");
    
    	return 0;
    }
    Perfect it works fine, my question is, how do I make possible something like that:
    Code:
    char joined[100];
    
    joined = join ("lala","lele",':',sizeof(buf));
    When I try to create a string in the function, and return it it says returning temp variable don't know what, and I receive a lot of $$$$s.

  2. #2
    .........
    Join Date
    Nov 2002
    Posts
    303
    Hmm I might be totally off here but I do not think you can actually
    return an array from a function. I think the the only way is to use an output parameter like you have been using.

    EDIT- you could use strcpy and i think that would give you what you want? but im sure you alrdy know this heh
    Last edited by SourceCode; 03-23-2003 at 03:55 AM.

  3. #3
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273
    It's complaining because you're statically allocating memory inside the function and then passing a pointer to it outside the function. Statically allocated memory is deallocated at the end of the function its declared in, so you'd receive an invalid pointer.

    If you want to do it that way, you're gonna have to dynamically allocate memory for "buf" (i.e. use malloc(...)) and then return a pointer to it, although you'll have to remember to free(...) it when you've finished with it.

  4. #4
    Registered User Vber's Avatar
    Join Date
    Nov 2002
    Posts
    807
    and when exactly I can safe free() this memory? I want buf to stay with the value until I end my program.
    Last edited by Vber; 03-23-2003 at 05:04 AM.

  5. #5
    Registered User Vber's Avatar
    Join Date
    Nov 2002
    Posts
    807
    Ok, after sometime, I did it, now I need to know if I'm doing it right, it's my first time I use malloc.

    Code:
    char *buf;
    
    if((buf = (char *) malloc(100 * sizeof *buf)) == NULL) {
    		printf("Could not allocate memory\n");
    		exit(1);
    	}
    Is this a correct way to allocate the memory? also, I just free this memory at the end of the program... before return 0, is this right too? also, when I do something like:
    Code:
    buf = join (':',"Lalawddw","Lele");
    	printf("buf : %s\n",buf);
    
    	buf1 = join('.',"jonhhh","jsjsjs");
    	printf("buf1: %s\n",buf1);
    It prints fine, but how do I free() the memory of buf1 since I don't know I allocated him as the same name of buf, I mean I just do free(buf), I need to make free(buf1) too?
    Last edited by Vber; 03-23-2003 at 06:54 AM.

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Is this a correct way to allocate the memory?
    Yes, except the cast isn't needed.

    > but how do I free() the memory of buf1 since I don't know I allocated him as the same name of buf
    You did allocate buf1 the same way as buf, with malloc in the join function. Just use
    Code:
    free ( buf );
    free ( buf1 );
    -Prelude
    My best code is written with the delete key.

  7. #7
    Registered User Vber's Avatar
    Join Date
    Nov 2002
    Posts
    807
    Without the cast:
    Code:
    C:\Cpp1.cpp(8) : error C2440: '=' : cannot convert from 'void *' to 'char *'
            Conversion from 'void*' to pointer to non-'void' requires an explicit cast
    Thanks prelude.

  8. #8
    .........
    Join Date
    Nov 2002
    Posts
    303
    Compile it as a C file and the error will go away.

  9. #9
    Registered User Vber's Avatar
    Join Date
    Nov 2002
    Posts
    807
    Ok, no more errors, now, isn't there anyway my program could alone free the memory I allocated? I think I'm asking too much

  10. #10
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >now, isn't there anyway my program could alone free the memory I allocated?
    Perhaps if you write your own garbage collector (not easy) or rely on the system reclaiming your memory (not a good practice). Otherwise, just using ISO C you can't.

    -Prelude
    My best code is written with the delete key.

  11. #11
    Registered User Vber's Avatar
    Join Date
    Nov 2002
    Posts
    807
    Thanks again Prelude, at least until now, I won't try to create my garbage collector, the final result, and this is what I wanted is:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    
    char *join (char ch, ...) {
    	char *buf,*s;
    	int i = 0, j = 0;
    	
    	va_list ap;
    	va_start(ap,ch);
    
    
    	//alocatte memory
    	if ((buf = (char *) malloc(1000 * sizeof(*buf))) == NULL) {
    		printf("Could not allocate memory\n");
    		exit(1);
    	}
    
    	while(s = va_arg(ap,char*)) {
    		for (j = 0; s[j]; j++)
    			buf[i++] = s[j];
    		buf[i++] = ch;
    	}
    
    	buf[--i] = '\0'; //delete the last ':' occurence and add \0
    	
    	return buf;
    }
    
    int main(void) {
    	char *test;
    
    	test = join(':',"lele","loli","loaaa","sshshsh");
    	printf("%s\n",test);
    	free(test);
    	return 0;
    }
    Thank you very much.

  12. #12
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    I think you need to ensure your function call has a NULL as its last parameter. For example:

    >>test = join(':',"lele","loli","loaaa","sshshsh", NULL);

    That way your loop knows when to stop:
    >>while((s = va_arg(ap,char*))!= NULL)

    Without this NULL on the function call, the loop will continue to process to memory outside the bounds.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Recursion: base case returning 1, function returning 0
    By yougene in forum C Programming
    Replies: 5
    Last Post: 09-07-2007, 05:38 PM
  2. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  3. Calling a Thread with a Function Pointer.
    By ScrollMaster in forum Windows Programming
    Replies: 6
    Last Post: 06-10-2006, 08:56 AM
  4. Function returning a function
    By shawn_drn in forum C++ Programming
    Replies: 6
    Last Post: 09-14-2004, 09:09 AM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM