strcpy

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Mike Mimic

    strcpy

    Hi!

    Is it possible to write this (and that it will work):

    char *buffer = ... // some array of chars terminated by \0 (allocated

    // with new and filled somewhere else)
    int t = ... // some value - how much to delete at the begining

    char *rest = new char[strlen(buffer) - t + 1];
    strcpy(rest, buffer + t);
    delete[] buffer;
    buffer = rest;

    in this way:

    char *buffer = ... // some array of chars terminated by \0 (allocated

    // with new and filled somewhere else)
    int t = ... // some value - how much to delete at the begining

    strcpy(buffer, buffer + t);

    (This is only a code simmilar to that in my program but the idea is
    here, t is always smaller than length.)


    Mike
  • John Harrison

    #2
    Re: strcpy


    "Mike Mimic" <ppagee@yahoo.c om> wrote in message
    news:c87itd$2cp $1@planja.arnes .si...[color=blue]
    > Hi!
    >
    > Is it possible to write this (and that it will work):
    >
    > char *buffer = ... // some array of chars terminated by \0 (allocated
    >
    > // with new and filled somewhere else)
    > int t = ... // some value - how much to delete at the begining
    >
    > char *rest = new char[strlen(buffer) - t + 1];
    > strcpy(rest, buffer + t);
    > delete[] buffer;
    > buffer = rest;
    >
    > in this way:
    >
    > char *buffer = ... // some array of chars terminated by \0 (allocated
    >
    > // with new and filled somewhere else)
    > int t = ... // some value - how much to delete at the begining
    >
    > strcpy(buffer, buffer + t);
    >[/color]

    No, the behaviour of strcpy is undefined if the source and destination
    strings overlap.

    You can use memmove instead which is guaranteed to work even for overlapping
    memory blocks

    memmove(buffer, buffer + t, strlen(buffer + t) + 1);

    john


    Comment

    • Simon Saunders

      #3
      Re: strcpy

      On Sun, 16 May 2004 13:22:25 +0200, Mike Mimic wrote:
      [color=blue]
      > Hi!
      >
      > Is it possible to write this (and that it will work):
      >
      > char *buffer = ... // some array of chars terminated by \0 (allocated
      >
      > // with new and filled somewhere else)
      > int t = ... // some value - how much to delete at the begining
      >
      > char *rest = new char[strlen(buffer) - t + 1];
      > strcpy(rest, buffer + t);
      > delete[] buffer;
      > buffer = rest;
      >
      > in this way:
      >
      > strcpy(buffer, buffer + t);
      >[/color]

      strcpy isn't required to work properly when the source and destination
      overlap; for that case you need memmove.

      Comment

      • Julie

        #4
        Re: strcpy

        John Harrison wrote:[color=blue]
        >
        > "Mike Mimic" <ppagee@yahoo.c om> wrote in message
        > news:c87itd$2cp $1@planja.arnes .si...[color=green]
        > > Hi!
        > >
        > > Is it possible to write this (and that it will work):
        > >
        > > char *buffer = ... // some array of chars terminated by \0 (allocated
        > >
        > > // with new and filled somewhere else)
        > > int t = ... // some value - how much to delete at the begining
        > >
        > > char *rest = new char[strlen(buffer) - t + 1];
        > > strcpy(rest, buffer + t);
        > > delete[] buffer;
        > > buffer = rest;
        > >
        > > in this way:
        > >
        > > char *buffer = ... // some array of chars terminated by \0 (allocated
        > >
        > > // with new and filled somewhere else)
        > > int t = ... // some value - how much to delete at the begining
        > >
        > > strcpy(buffer, buffer + t);
        > >[/color]
        >
        > No, the behaviour of strcpy is undefined if the source and destination
        > strings overlap.
        >
        > You can use memmove instead which is guaranteed to work even for overlapping
        > memory blocks
        >
        > memmove(buffer, buffer + t, strlen(buffer + t) + 1);
        >
        > john[/color]

        Should be:

        memmove(buffer, buffer + t, (strlen(buffer+ t)+1)*sizeof(*b uffer));

        Comment

        • John Harrison

          #5
          Re: strcpy


          "Julie" <julie@nospam.c om> wrote in message
          news:40A8D070.8 C571F42@nospam. com...[color=blue]
          > John Harrison wrote:[color=green]
          > >
          > > "Mike Mimic" <ppagee@yahoo.c om> wrote in message
          > > news:c87itd$2cp $1@planja.arnes .si...[color=darkred]
          > > > Hi!
          > > >
          > > > Is it possible to write this (and that it will work):
          > > >
          > > > char *buffer = ... // some array of chars terminated by \0 (allocated
          > > >
          > > > // with new and filled somewhere else)
          > > > int t = ... // some value - how much to delete at the begining
          > > >
          > > > char *rest = new char[strlen(buffer) - t + 1];
          > > > strcpy(rest, buffer + t);
          > > > delete[] buffer;
          > > > buffer = rest;
          > > >
          > > > in this way:
          > > >
          > > > char *buffer = ... // some array of chars terminated by \0 (allocated
          > > >
          > > > // with new and filled somewhere else)
          > > > int t = ... // some value - how much to delete at the begining
          > > >
          > > > strcpy(buffer, buffer + t);
          > > >[/color]
          > >
          > > No, the behaviour of strcpy is undefined if the source and destination
          > > strings overlap.
          > >
          > > You can use memmove instead which is guaranteed to work even for[/color][/color]
          overlapping[color=blue][color=green]
          > > memory blocks
          > >
          > > memmove(buffer, buffer + t, strlen(buffer + t) + 1);
          > >
          > > john[/color]
          >
          > Should be:
          >
          > memmove(buffer, buffer + t, (strlen(buffer+ t)+1)*sizeof(*b uffer));[/color]

          Why? sizeof(*buffer) is guaranteed to be one. Or are you making a stylistic
          comment?

          john


          Comment

          • Julie

            #6
            Re: strcpy

            John Harrison wrote:[color=blue]
            >
            > "Julie" <julie@nospam.c om> wrote in message
            > news:40A8D070.8 C571F42@nospam. com...[color=green]
            > > John Harrison wrote:[color=darkred]
            > > >
            > > > "Mike Mimic" <ppagee@yahoo.c om> wrote in message
            > > > news:c87itd$2cp $1@planja.arnes .si...
            > > > > Hi!
            > > > >
            > > > > Is it possible to write this (and that it will work):
            > > > >
            > > > > char *buffer = ... // some array of chars terminated by \0 (allocated
            > > > >
            > > > > // with new and filled somewhere else)
            > > > > int t = ... // some value - how much to delete at the begining
            > > > >
            > > > > char *rest = new char[strlen(buffer) - t + 1];
            > > > > strcpy(rest, buffer + t);
            > > > > delete[] buffer;
            > > > > buffer = rest;
            > > > >
            > > > > in this way:
            > > > >
            > > > > char *buffer = ... // some array of chars terminated by \0 (allocated
            > > > >
            > > > > // with new and filled somewhere else)
            > > > > int t = ... // some value - how much to delete at the begining
            > > > >
            > > > > strcpy(buffer, buffer + t);
            > > > >
            > > >
            > > > No, the behaviour of strcpy is undefined if the source and destination
            > > > strings overlap.
            > > >
            > > > You can use memmove instead which is guaranteed to work even for[/color][/color]
            > overlapping[color=green][color=darkred]
            > > > memory blocks
            > > >
            > > > memmove(buffer, buffer + t, strlen(buffer + t) + 1);
            > > >
            > > > john[/color]
            > >
            > > Should be:
            > >
            > > memmove(buffer, buffer + t, (strlen(buffer+ t)+1)*sizeof(*b uffer));[/color]
            >
            > Why? sizeof(*buffer) is guaranteed to be one. Or are you making a stylistic
            > comment?
            >
            > john[/color]

            No, stylistic comment, but:

            - strlen returns a character count, memmove takes a byte count, multiplying
            simply converts from char count to bytes.

            - More importantly, if the user changes from ASCII to Unicode (or other mbcs),
            then their code is much more portable/convertible.

            In this day and age, it is no longer safe to make assumptions that
            sizeof('charact er type') == 1

            Comment

            • Peter Koch Larsen

              #7
              Re: strcpy


              "Julie" <julie@nospam.c om> skrev i en meddelelse
              news:40A8FE66.B E4A1902@nospam. com...[color=blue]
              > John Harrison wrote:[color=green]
              > >
              > > "Julie" <julie@nospam.c om> wrote in message
              > > news:40A8D070.8 C571F42@nospam. com...[color=darkred]
              > > > John Harrison wrote:
              > > > >
              > > > > "Mike Mimic" <ppagee@yahoo.c om> wrote in message
              > > > > news:c87itd$2cp $1@planja.arnes .si...
              > > > > > Hi!
              > > > > >
              > > > > > Is it possible to write this (and that it will work):
              > > > > >
              > > > > > char *buffer = ... // some array of chars terminated by \0[/color][/color][/color]
              (allocated[color=blue][color=green][color=darkred]
              > > > > >
              > > > > > // with new and filled somewhere else)
              > > > > > int t = ... // some value - how much to delete at the begining
              > > > > >
              > > > > > char *rest = new char[strlen(buffer) - t + 1];
              > > > > > strcpy(rest, buffer + t);
              > > > > > delete[] buffer;
              > > > > > buffer = rest;
              > > > > >
              > > > > > in this way:
              > > > > >
              > > > > > char *buffer = ... // some array of chars terminated by \0[/color][/color][/color]
              (allocated[color=blue][color=green][color=darkred]
              > > > > >
              > > > > > // with new and filled somewhere else)
              > > > > > int t = ... // some value - how much to delete at the begining
              > > > > >
              > > > > > strcpy(buffer, buffer + t);
              > > > > >
              > > > >
              > > > > No, the behaviour of strcpy is undefined if the source and[/color][/color][/color]
              destination[color=blue][color=green][color=darkred]
              > > > > strings overlap.
              > > > >
              > > > > You can use memmove instead which is guaranteed to work even for[/color]
              > > overlapping[color=darkred]
              > > > > memory blocks
              > > > >
              > > > > memmove(buffer, buffer + t, strlen(buffer + t) + 1);
              > > > >
              > > > > john
              > > >
              > > > Should be:
              > > >
              > > > memmove(buffer, buffer + t, (strlen(buffer+ t)+1)*sizeof(*b uffer));[/color]
              > >
              > > Why? sizeof(*buffer) is guaranteed to be one. Or are you making a[/color][/color]
              stylistic[color=blue][color=green]
              > > comment?
              > >
              > > john[/color]
              >
              > No, stylistic comment, but:
              >
              > - strlen returns a character count, memmove takes a byte count,[/color]
              multiplying[color=blue]
              > simply converts from char count to bytes.[/color]

              And - as John said - they are exactly the same.[color=blue]
              >
              > - More importantly, if the user changes from ASCII to Unicode (or other[/color]
              mbcs),[color=blue]
              > then their code is much more portable/convertible.[/color]

              Well... that could be argued. The code probably deserves a major review if
              not using plain chars.
              [color=blue]
              >
              > In this day and age, it is no longer safe to make assumptions that
              > sizeof('charact er type') == 1[/color]

              /Peter


              Comment

              • Julie

                #8
                Re: strcpy

                Peter Koch Larsen wrote:[color=blue][color=green][color=darkred]
                > > > > > You can use memmove instead which is guaranteed to work even for
                > > > overlapping
                > > > > > memory blocks
                > > > > >
                > > > > > memmove(buffer, buffer + t, strlen(buffer + t) + 1);
                > > > > >
                > > > > > john
                > > > >
                > > > > Should be:
                > > > >
                > > > > memmove(buffer, buffer + t, (strlen(buffer+ t)+1)*sizeof(*b uffer));
                > > >
                > > > Why? sizeof(*buffer) is guaranteed to be one. Or are you making a[/color][/color]
                > stylistic[color=green][color=darkred]
                > > > comment?
                > > >
                > > > john[/color]
                > >
                > > No, stylistic comment, but:
                > >
                > > - strlen returns a character count, memmove takes a byte count,[/color]
                > multiplying[color=green]
                > > simply converts from char count to bytes.[/color]
                >
                > And - as John said - they are exactly the same.[color=green]
                > >
                > > - More importantly, if the user changes from ASCII to Unicode (or other[/color]
                > mbcs),[color=green]
                > > then their code is much more portable/convertible.[/color]
                >
                > Well... that could be argued. The code probably deserves a major review if
                > not using plain chars.[/color]

                No disagreement for changes to existing code -- it should be reviewed in
                detail.

                However, any new code should be built to be as portable to non _char_ character
                types. Duty now for the future.

                [color=blue][color=green]
                > >
                > > In this day and age, it is no longer safe to make assumptions that
                > > sizeof('charact er type') == 1[/color]
                >
                > /Peter[/color]

                Comment

                • John Harrison

                  #9
                  Re: strcpy

                  >[color=blue]
                  > - More importantly, if the user changes from ASCII to Unicode (or other[/color]
                  mbcs),[color=blue]
                  > then their code is much more portable/convertible.
                  >
                  > In this day and age, it is no longer safe to make assumptions that
                  > sizeof('charact er type') == 1[/color]

                  If the change is made from ASCII to Unicode then the call to strlen would
                  also need to change to wcslen. I'd hope sizeof would be added at the same
                  time.

                  I'm not disagreeing with you, but I don't think I'd be bothered with sizeof,
                  if I wrote the code.

                  john


                  Comment

                  • Peter Koch Larsen

                    #10
                    Re: strcpy


                    "Julie" <julie@nospam.c om> skrev i en meddelelse
                    news:40A907C4.7 4D836AD@nospam. com...[color=blue]
                    > Peter Koch Larsen wrote:[/color]
                    [snip9[color=blue][color=green][color=darkred]
                    > > > > > memmove(buffer, buffer + t, (strlen(buffer+ t)+1)*sizeof(*b uffer));
                    > > > >
                    > > > > Why? sizeof(*buffer) is guaranteed to be one. Or are you making a[/color]
                    > > stylistic[color=darkred]
                    > > > > comment?
                    > > > >
                    > > > > john
                    > > >
                    > > > No, stylistic comment, but:
                    > > >
                    > > > - strlen returns a character count, memmove takes a byte count,[/color]
                    > > multiplying[color=darkred]
                    > > > simply converts from char count to bytes.[/color]
                    > >
                    > > And - as John said - they are exactly the same.[color=darkred]
                    > > >
                    > > > - More importantly, if the user changes from ASCII to Unicode (or[/color][/color][/color]
                    other[color=blue][color=green]
                    > > mbcs),[color=darkred]
                    > > > then their code is much more portable/convertible.[/color]
                    > >
                    > > Well... that could be argued. The code probably deserves a major review[/color][/color]
                    if[color=blue][color=green]
                    > > not using plain chars.[/color]
                    >
                    > No disagreement for changes to existing code -- it should be reviewed in
                    > detail.
                    >
                    > However, any new code should be built to be as portable to non _char_[/color]
                    character[color=blue]
                    > types. Duty now for the future.[/color]

                    Of course. But the code shown was not in any way in a condition that you
                    might consider porting it anyway.
                    [color=blue]
                    >
                    >[color=green][color=darkred]
                    > > >
                    > > > In this day and age, it is no longer safe to make assumptions that
                    > > > sizeof('charact er type') == 1[/color]
                    > >
                    > > /Peter[/color][/color]


                    Comment

                    Working...