use of C memmove

Steven Schveighoffer schveiguy at yahoo.com
Thu Apr 7 11:12:02 PDT 2011


On Thu, 07 Apr 2011 13:09:05 -0400, spir <denis.spir at gmail.com> wrote:

> Hello,
>
> I'm trying to use C's memmove as a tool to delete or insert a slice  
> from/into an array. But I cannot manage to do it: systematic  
> segmentation fault.
> What is wrong below?
>
> import std.c.string : memmove;
> // void *memmove(void *dest, const void *src, size_t n);
>
> void moveEnd (E) (E[] elements, size_t start, int offset) {
>      // Length must be known before possible extension.
>      auto length = elements.length;
>
>      // If move up, extend array to make place.
>      if (offset > 0)
>          elements.length += offset;
>
>      // Move slice.
>      auto dest = cast(void*)(&(elements[start + offset]));
>      auto source = cast(void*)(&(elements[start]));
>      size_t size = length - start;
>      memmove(dest, source, size);    // segfault ***
>
>      // If move down, compress array.
>      if (offset < 0)
>          elements.length += offset;
> }
>
> unittest {
>      string s = "012--3456789";
>      // Remove slice.
>      s.moveEnd(5, -2);
>      writeln(s);
> }

Two problems.  One is, the memmove size_t n is number of *bytes*, not  
number of elements as you have expected.  You probably would have noticed  
this quickly if the other problem wasn't there.

The other problem is, strings literals are immutable.  On Windows, this  
code may have worked, but Linux protects the pages of static data, so  
writing to a string literal creates a seg fault.

Try this:

auto s = "012--3456789".dup; // convert to char[]

To fix first problem use memmove(dest, source, size * (E).sizeof);

-Steve


More information about the Digitalmars-d-learn mailing list