Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
April 07, 2011 use of C memmove | ||||
---|---|---|---|---|
| ||||
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); } Denis -- _________________ vita es estrany spir.wikidot.com |
April 07, 2011 Re: use of C memmove | ||||
---|---|---|---|---|
| ||||
Posted in reply to spir | On Thu, 07 Apr 2011 13:09:05 -0400, spir <denis.spir@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
|
April 07, 2011 Re: use of C memmove | ||||
---|---|---|---|---|
| ||||
Posted in reply to spir | spir Wrote:
> // If move down, compress array.
> if (offset < 0)
> elements.length += offset;
ow, addAssign works on length?
|
April 07, 2011 Re: use of C memmove | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Thu, 07 Apr 2011 14:44:28 -0400, Kagamin <spam@here.lot> wrote: > spir Wrote: > >> // If move down, compress array. >> if (offset < 0) >> elements.length += offset; > > ow, addAssign works on length? Since 12/09 :) http://www.digitalmars.com/d/2.0/changelog.html#new2_037 -Steve |
April 07, 2011 Re: use of C memmove | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 04/07/2011 08:12 PM, Steven Schveighoffer wrote: > On Thu, 07 Apr 2011 13:09:05 -0400, spir <denis.spir@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); Thank you very much, Steven! Denis -- _________________ vita es estrany spir.wikidot.com |
Copyright © 1999-2021 by the D Language Foundation