Thread: how to implement a function

  1. #1
    Registered User
    Join Date
    Mar 2012
    Posts
    4

    how to implement a function

    Hello

    given the following code:
    Code:
      
    void func(){ 
    char *var=NULL; 
    str_cpy(var,"text1"); 
    str_cpy(var,var+2); 
    some print(var) // result: xt1 
    some_free(var) 
    }
    i should implement the str_cpy function.
    how would you implement it efficiently (without memory leaks)?
    Last edited by BMWE; 03-25-2012 at 01:47 PM.

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    What have you tried?

    Edit: With the improved formatting in your code, I can see that there's no real useful str_cpy() that can be written. You'd at the very least have to return a value from str_cpy() and assign it to var.
    Last edited by cas; 03-25-2012 at 01:50 PM.

  3. #3
    Registered User
    Join Date
    Mar 2012
    Posts
    4
    actually to solve this problem, i should call to allocate memory when i call to str_cpy.
    but when i call it on second time, there will be memory leak if no free memory function will be called.
    but if i ask to free memory before allocating a new one, then i lose data (i'm also free the input)

  4. #4
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    Strcpy() doesn't have memory leaks. It's actually one of the faster and most reliable string library functions. Of course, the way you're using it, it will crash, because you're trying to write data to address 0x0 in memory, which won't work no matter what string copy function you use. You have to allocate memory first, with malloc() or by using an array.

    If you're looking to write a more efficient strcpy function (which will be very difficult, as the default is highly optimized), you could try:
    • Copying the data in larger blocks of data, by using unsigned long long (8 bytes) or xmm registers that can hold up to sixteen bytes at a time.
    • Writing the loop in assembly so you can access the said xmm registers, and bypass the stack access by only writing to and from registers and memory
    • Prefetching data before you copy if your architecture's documentation specifies that this will improve performance
    • Aligning data before and during the copy if your architecture can handle aligned i/o faster than unaligned i/o (most can)
    • Unrolling the loop and copying multiple blocks of 16 bytes in each iteration
    • Checking for zero (when to stop copying) with the mmx-specific "pcmpeq", "pmovmskb", and "bsf" instructions. You can find examples online on how to implement them in assembly.


    Also, you might want to check out a quick strlen() rendition I scrapped together, as knowing the length beforehand will speed up the copy:
    Code:
    .globl _asm_strlen
    _asm_strlen:
    	movq     %rdi, %rax
    	pxor     %xmm0, %xmm0
    	andq     $-16, %rax
    ln_loop:     
    	addq     $16, %rax
    	movdqa   (%rax), %xmm1
    	pcmpeqb  %xmm0, %xmm1
    	pmovmskb %xmm1, %edx
    	bsf      %edx, %edx
    	jz       ln_loop
    	subq     %rdi, %rax
    	addq     %rdx, %rax
    	ret
    Note: you can find something _similar_ by disassembling the default strlen() command in a debugger.

  5. #5
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by BMWE View Post
    actually to solve this problem, i should call to allocate memory when i call to str_cpy.
    but when i call it on second time, there will be memory leak if no free memory function will be called.
    but if i ask to free memory before allocating a new one, then i lose data (i'm also free the input)
    It can be avoided if you start by checking if the pointer you pass to the function is NULL. If it is, then you know it's the first time the pointer is used. If it isn't, then you concatenate to the existing string.

    This requires that you initialize your pointer to NULL before you use it, which you have done in your example.

    Quote Originally Posted by memcpy View Post
    Strcpy() doesn't have memory leaks. It's actually one of the faster and most reliable string library functions. Of course, the way you're using it, it will crash, because you're trying to write data to address 0x0 in memory, which won't work no matter what string copy function you use. You have to allocate memory first, with malloc() or by using an array.
    I may have missed something here but I think the objective is to create such string copy function called str_cpy(). It will allocate memory for the receiver if the pointer is NULL, other wise concatenate to the existing string.
    Last edited by Subsonics; 03-25-2012 at 02:14 PM.

  6. #6
    Registered User
    Join Date
    Mar 2012
    Posts
    4
    @Subsonics, but then - how you are going to free the memory?

  7. #7
    Registered User
    Join Date
    Mar 2012
    Posts
    4
    right now the only solution i see is
    Code:
    void str_cpy (char **dest, const char *source)
    {    
            int len = strlen(source);
            if (char *tmp=(char *)malloc(sizeof(char)*(len+1)))
           {
                   memmove(tmp,source,len);
                   tmp[len]=0;
                   str_free(dest);
                   if (*dest=(char *)malloc(sizeof(char)*(len+1)))
                  {
                          *dest=tmp;
                  }
       }        
    }

  8. #8
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by BMWE View Post
    @Subsonics, but then - how you are going to free the memory?
    I'm not sure what you mean, you pass the pointer to the function, so you can always free it after you are done with it. If you need to you realloc or create a new temporary string inside it in your implementation then you can free the old string inside the function and switch the pointer values in the function. Although as cas points out if you want this to have effect outside your function you need to either return the pointer or pass in the address of the pointer to the function.

  9. #9
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by BMWE View Post
    right now the only solution i see is
    Code:
    void str_cpy (char **dest, const char *source)
    {    
            int len = strlen(source);
            if (char *tmp=(char *)malloc(sizeof(char)*(len+1)))
           {
                   memmove(tmp,source,len);
                   tmp[len]=0;
                   str_free(dest);
                   if (*dest=(char *)malloc(sizeof(char)*(len+1)))
                  {
                          *dest=tmp;
                  }
       }        
    }
    Right, but you could start by checking if *dest == NULL. If it is you allocate strlen(source) +1 to *dest.

    If *dest is not NULL, you reallocate *dest with strlen(*dest) + strlen(source) +1 and concatenate source to dest.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 11-15-2011, 10:49 PM
  2. how to implement in C++
    By nageshrk1 in forum C++ Programming
    Replies: 7
    Last Post: 02-20-2010, 01:16 PM
  3. Replies: 10
    Last Post: 06-24-2008, 09:50 AM
  4. Replies: 9
    Last Post: 11-12-2007, 03:29 PM
  5. How do I implement a Tempo function in my sequencer?
    By electrolove in forum C Programming
    Replies: 7
    Last Post: 02-17-2003, 04:29 AM