Thread: working with srings adresses and pointers,

  1. #1
    Registered User
    Join Date
    Apr 2014
    Posts
    26

    working with srings adresses and pointers,

    I was trying to do an exercise, but, because i still dont understand adresses very well i dont think my solution is quite right.

    the exercise is the following:

    -----------------------------------------------------------
    move n bytes from area m2 to area m1 (this function must work even if m1 and m2 share memory space).
    -----------------------------------------------------------

    the exercise is, in my opinion, with a confusing choice of words. It is related to strings so area m2 and area m1 are strings.

    My solution gives the result that is expected, i mean, it recieves string 1, string 2 and n bytes to move and it does it, but i think im creating a new memory space for this wich is not what is intended. Do i need to use adresses here? well my solution is the following:


    Code:
    #include <stdio.h>
    
    void movefunction(char m1[], char m2[], int n);
    
    int main() 
    {
    
    char m1[1000];
    char m2[1000];
    int n;
    
    printf("write string 1 \n");    
    scanf("%s", m1);
    printf("write string 2 \n");
    scanf("%s",m2);    
    printf("write the number of bytes to move\n");
    scanf("%d",&n);
    
    movefunction(m1, m2, n);
    
    printf("%s", m1);
    
    return 0;
    
    }
    
    
    void movefunction(char s1[], char s2[], int n){
       int i;
       i=0;
       while (i!=n){
          s1[i] = s2[i];
          i++;
       }
    }

  2. #2
    Registered User
    Join Date
    Sep 2008
    Posts
    200
    Quote Originally Posted by Lired View Post
    but i think im creating a new memory space for this wich is not what is intended.
    You are not - your movefunction() acts on the m1 and m2 you pass it (i.e. in this case, the ones declared in your main() function), so you're okay on that front.

    However, the exercise states that "this function must work even if m1 and m2 share memory space", i.e. if they overlap; however, yours will not - think about if you did e.g. "movefunction(&m1[1], &m1[0], n)". Before you fix this, I suggest you write a small test case to show you that it's broken. To fix, you need to allocate a new array, copy all the contents of the source buffer in there, then copy them all to the destination buffer, then free the array. If you're allowed to use variable-length arrays, you can just declare a new array "char tmp[n]" in your function - otherwise you'll have to use malloc()/free().
    Programming and other random guff: cat /dev/thoughts > blogspot.com (previously prognix.blogspot.com)

    ~~~

    "The largest-scale pattern in the history of Unix is this: when and where Unix has adhered most closely to open-source practices, it has prospered. Attempts to proprietarize it have invariably resulted in stagnation and decline."

    Eric Raymond, The Art of Unix Programming

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    It can be done without the temporary array, but it takes some thought. Some questions that can help you figure out how are: how far apart s1 and s2 are, which has the higher memory address, and how big n is.

  4. #4
    Registered User
    Join Date
    Apr 2014
    Posts
    26
    Quote Originally Posted by JohnGraham View Post
    You are not - your movefunction() acts on the m1 and m2 you pass it (i.e. in this case, the ones declared in your main() function), so you're okay on that front.

    However, the exercise states that "this function must work even if m1 and m2 share memory space", i.e. if they overlap; however, yours will not - think about if you did e.g. "movefunction(&m1[1], &m1[0], n)". Before you fix this, I suggest you write a small test case to show you that it's broken. To fix, you need to allocate a new array, copy all the contents of the source buffer in there, then copy them all to the destination buffer, then free the array. If you're allowed to use variable-length arrays, you can just declare a new array "char tmp[n]" in your function - otherwise you'll have to use malloc()/free().

    well i dont think i quite understand. are u saying to use another string equal to m2 that, because it is a diferent variable has a different memory location? for example, like this:

    Code:
    void movefunction (char m1[], char m2[], int n){
        char temp[1000];
        int i;
    
        if(((m1-m2)<0)||((m1-m2)<n)){
            for (i=0;i!=n;i++){
                    temp[i] = m2[i];
                }
            for (i=0;i!=n;i++){
                    m1[i] = temp[i];
                }
        }
        else {
            for (i=0;i!=n;i++){
                       m1[i] = m2[i];
                }
        }
    }

    and also the example where you were saying it didnt work, was it, for example,

    m1="sl"
    m2="o"
    n=2
    returns "o"

    ?

    i guess here it should return "ol" but it doesn't...
    Last edited by Lired; 04-17-2014 at 05:29 PM.

  5. #5
    Registered User
    Join Date
    Apr 2014
    Posts
    26
    or maybe not because

    m1="sl"
    m2="o"
    n=2
    returns "o"

    is also moving the \0 so thats why the string stops at "o"

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by anduril462 View Post
    It can be done without the temporary array, but it takes some thought.
    Not if you mean using pointer comparisons (other than equality/inequality). The behaviour of comparison operations other than equality and inequality are undefined if the two pointers don't point to parts of the same object (or array with "one past its end").

    Personally, I'd use memmove(), but I suppose that's not the point of the exercise.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by grumpy View Post
    Not if you mean using pointer comparisons (other than equality/inequality). The behaviour of comparison operations other than equality and inequality are undefined if the two pointers don't point to parts of the same object (or array with "one past its end").

    Personally, I'd use memmove(), but I suppose that's not the point of the exercise.
    Dang it! You're right, I totally forgot about that. Sad thing is, I've looked up and quoted that part of the standard here more than once, so I should've known better.

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Damn! I was hoping you had another approach to do it, which didn't involve such pointer comparisons.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  9. #9
    Registered User
    Join Date
    Apr 2014
    Posts
    4
    In fact you can do smth like this:

    Code:
    #include <stdio.h>
    #include <string.h>
    #define MIN(a,b) ((a)<(b)) ? a:b;
    void movefunction(char m1[], char m2[], int n);
     
    int main() 
    {
     
    char m1[1000];
    char m2[1000];
    int n;
     
    printf("write string 1 \n");    
    scanf("%s", m1);
    printf("write string 2 \n");
    scanf("%s",m2);    
    printf("write the number of bytes to move\n");
    scanf("%d",&n);
     
    movefunction(m1, m2, n);
     
    printf("%s", m1);
    
    
    return 0;
     
    }
     
     
    void movefunction(char *s1, char *s2, int n){
       int i,move;
       move=MIN(strlen(s1),n);
       move=MIN(strlen(s2),move);
       for (i=0; i<move; i++,s1++,s2++)
              *s1 = *s2;
    }
    So you will use pointers and you will not run out of strings lengths
    Last edited by Omen; 04-18-2014 at 04:32 AM.

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    That will not work if the strings overlap, Omen - among other things.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  11. #11
    Registered User
    Join Date
    Apr 2014
    Posts
    4
    Maybe, I didn't get the problem... I thought I have to change first n bytes of string one in the first n bytes of string two. No?

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Omen View Post
    Maybe, I didn't get the problem... I thought I have to change first n bytes of string one in the first n bytes of string two. No?
    No. Look at post #2.

    Also, to reiterate a reply I gave to your other post, it is against site policy to just give complete code solutions.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  13. #13
    Registered User
    Join Date
    Apr 2014
    Posts
    4
    Yes. I saw it. But I can't edit my post in this thread unfortunately...

  14. #14
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by grumpy View Post
    Damn! I was hoping you had another approach to do it, which didn't involve such pointer comparisons.
    Well, there is a way using just the == operator, but it's something of a cop out, and wildly inefficient. It's order 2n operations worst case just to find if they overlap and which comes first. Then you still have to copy.

  15. #15
    Registered User
    Join Date
    Apr 2014
    Posts
    26
    So the code i posted before, this one:

    Code:
    void movefunction (char m1[], char m2[], int n){
        char temp[1000];
        int i;
     
        if(((m1-m2)<0)||((m1-m2)<n)){
            for (i=0;i!=n;i++){
                    temp[i] = m2[i];
                }
            for (i=0;i!=n;i++){
                    m1[i] = temp[i];
                }
        }
        else {
            for (i=0;i!=n;i++){
                       m1[i] = m2[i];
                }
        }
    }

    is still wrong?? Doesn't it correct the situation in wich they overlap?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 06-01-2007, 07:02 PM
  2. Working with pointers...
    By CompiledMonkey in forum C++ Programming
    Replies: 2
    Last Post: 05-09-2005, 08:14 AM
  3. Ip adresses
    By Da-Nuka in forum Networking/Device Communication
    Replies: 8
    Last Post: 02-27-2005, 02:25 PM
  4. msn adresses on XP
    By GanglyLamb in forum Tech Board
    Replies: 1
    Last Post: 07-10-2003, 05:27 AM
  5. Increamenting Array Adresses
    By Code-Disciple in forum C++ Programming
    Replies: 1
    Last Post: 03-21-2003, 04:40 PM

Tags for this Thread