Re: Using "strcpy" to assign value to dynamic char array
On Thursday, 4 November 2021 at 01:29:57 UTC, jfondren wrote: On Monday, 1 November 2021 at 19:56:13 UTC, pascal111 wrote: But what if I want to use "strcpy" function to assign that new value to the array that the problem is that the array won't take more than its first initializing value length: { . . . assert(output == "ok\0Way t\0"); assert(output[0 .. strlen([0])] == "ok"); } ``` I appreciate your vary explanation.
Re: Using "strcpy" to assign value to dynamic char array
On Monday, 1 November 2021 at 19:56:13 UTC, pascal111 wrote: But what if I want to use "strcpy" function to assign that new value to the array that the problem is that the array won't take more than its first initializing value length: { char[] s="xyz".dup; strcpy([0], "Hello World!"); writeln(s); } Result: Hel Easy win: use normal operations with static arrays instead of strcpy: ```d unittest { char[3] s = "xyz"; s = "Hello World"; // Error: index [11] exceeds array of length 3 } ``` Now you'll get errors (in range-checked builds) instead of silent bad behavior. With a larger buffer, short assigns (only with string literals) zero the rest of the buffer: ```d unittest { char[15] s = "xyz"; s = "Hello World"; // this is OK assert(s == "Hello World\0\0\0\0"); } unittest { char[15] s = "Hello World"; s = "xyz"; // so is this assert(s[0 .. 5] == "xyz\0\0"); } ``` But more realistically you'll be getting strings from somewhere and can assign a specific region using the length of those strings: ```d unittest { // pretend these are user inputs string ex1 = "Hello World"; string ex2 = "xyz"; char[15] s; s[0 .. ex1.length] = ex1; assert(s == "Hello World\xFF\xFF\xFF\xFF"); s[0 .. ex2.length] = ex2; assert(s[0 .. ex1.length] == "xyzlo World"); } ``` This is all obviously much more of a hassle than normal D string-handling, but if you're going to apply C levels of care with memory and string handling, you can do that in D while still avoiding C levels of bugs. ```d unittest { import std.algorithm : min; import core.stdc.string : strlen; char[6] buf; string output; foreach (input; ["ok", "Way too long!"]) { auto len = min(buf.length-1, input.length); buf[0 .. len] = input[0 .. len]; buf[len] = '\0'; output ~= buf[0 .. len+1]; } assert(output == "ok\0Way t\0"); assert(output[0 .. strlen([0])] == "ok"); } ```
Re: Using "strcpy" to assign value to dynamic char array
On Wednesday, 3 November 2021 at 10:38:45 UTC, pascal111 wrote: On Wednesday, 3 November 2021 at 02:38:56 UTC, Steven Schveighoffer wrote: On 11/1/21 9:03 PM, pascal111 wrote: [...] [...] ... [...] Please please, do NOT study this code. It is bad all around. Ali should know better ;) He is joking with the code posted, it should not be used in any real code ever. Not only is it corrupting memory, it may not work as expected in all cases (and will randomly fail). Please learn first how memory works before writing the low-level bits of arrays! As a beginner, I suggest studying what a buffer overrun is, and why it is bad. -Steve I started to change my mind about doing things in low level of classic C, I started to think get benefits of new features of D. Good, you will be much happier ☀️
Re: Using "strcpy" to assign value to dynamic char array
On Wednesday, 3 November 2021 at 02:38:56 UTC, Steven Schveighoffer wrote: On 11/1/21 9:03 PM, pascal111 wrote: On Monday, 1 November 2021 at 21:32:21 UTC, Ali Çehreli wrote: Joking aside ... This function seems smart and flexible and higher than my current level, I'll study it. Please please, do NOT study this code. It is bad all around. Ali should know better ;) He is joking with the code posted, it should not be used in any real code ever. Not only is it corrupting memory, it may not work as expected in all cases (and will randomly fail). Please learn first how memory works before writing the low-level bits of arrays! As a beginner, I suggest studying what a buffer overrun is, and why it is bad. -Steve I started to change my mind about doing things in low level of classic C, I started to think get benefits of new features of D.
Re: Using "strcpy" to assign value to dynamic char array
On 11/2/21 9:06 PM, tsbockman wrote: UFCS works for setters, too: Oh yeah! Pretty cool. :) Ali
Re: Using "strcpy" to assign value to dynamic char array
On Monday, 1 November 2021 at 21:32:21 UTC, Ali Çehreli wrote: Joking aside, I liked the nested struct and its opAssign to mimic internal `arr.length = 42` syntax. (I know it involves a potentially expensive delegate but still...) The nested struct is not needed. UFCS works for setters, too: ```D void assumedLength(S)(ref S slice, size_t length) { if(slice.length >= length) slice.length = length; else assert(false, "Let's not corrupt memory today."); } void main() { auto arr = [ 1, 2, 3 ]; arr.assumedLength = 2; writeln(arr); } ```
Re: Using "strcpy" to assign value to dynamic char array
On 11/1/21 9:03 PM, pascal111 wrote: On Monday, 1 November 2021 at 21:32:21 UTC, Ali Çehreli wrote: Joking aside ... This function seems smart and flexible and higher than my current level, I'll study it. Please please, do NOT study this code. It is bad all around. Ali should know better ;) He is joking with the code posted, it should not be used in any real code ever. Not only is it corrupting memory, it may not work as expected in all cases (and will randomly fail). Please learn first how memory works before writing the low-level bits of arrays! As a beginner, I suggest studying what a buffer overrun is, and why it is bad. -Steve
Re: Using "strcpy" to assign value to dynamic char array
On Monday, 1 November 2021 at 21:37:59 UTC, Ali Çehreli wrote: On 11/1/21 2:28 PM, pascal111 wrote: > This can serve the style I want. I am feeling funny right now and showing incorrect code. It's impossible to fit "Hello World!" in "xyz". As Steve said, don't do that. :) > It uses OOP style like C++ by putting a > pointer as a property, D's slices are the equivalent of the following struct (showing for int): struct __Slice__ { size_t length; int * ptr; } So, .ptr is simply a member variable. (Assigning to .length does some magic like allocating more memory in some cases; otherwise it is a member variable as well.) > but pointers themselves are low level. arr.ptr is as low as it gets: It is a pointer. Ali Anyway, I'm a beginner and any information is useful to me.
Re: Using "strcpy" to assign value to dynamic char array
On Monday, 1 November 2021 at 21:32:21 UTC, Ali Çehreli wrote: On 11/1/21 2:01 PM, Ali Çehreli wrote: > The program is as incorrect as its C equivalent would be. ;) I wrote a cool function to make it easy to disregard memory safety: import std.stdio; auto assumedLength(S)(ref S slice) { struct LengthSetter { void opAssign(size_t length) { // Nooo! :) *cast(size_t*)() = length; } } return LengthSetter(); } void main() { auto arr = [ 1, 2, 3 ]; arr.assumedLength = 10; writeln(arr); } Joking aside, I liked the nested struct and its opAssign to mimic internal `arr.length = 42` syntax. (I know it involves a potentially expensive delegate but still...) Ali This function seems smart and flexible and higher than my current level, I'll study it.
Re: Using "strcpy" to assign value to dynamic char array
On 11/1/21 2:28 PM, pascal111 wrote: > This can serve the style I want. I am feeling funny right now and showing incorrect code. It's impossible to fit "Hello World!" in "xyz". As Steve said, don't do that. :) > It uses OOP style like C++ by putting a > pointer as a property, D's slices are the equivalent of the following struct (showing for int): struct __Slice__ { size_t length; int * ptr; } So, .ptr is simply a member variable. (Assigning to .length does some magic like allocating more memory in some cases; otherwise it is a member variable as well.) > but pointers themselves are low level. arr.ptr is as low as it gets: It is a pointer. Ali
Re: Using "strcpy" to assign value to dynamic char array
On 11/1/21 2:01 PM, Ali Çehreli wrote: > The program is as incorrect as its C equivalent would be. ;) I wrote a cool function to make it easy to disregard memory safety: import std.stdio; auto assumedLength(S)(ref S slice) { struct LengthSetter { void opAssign(size_t length) { // Nooo! :) *cast(size_t*)() = length; } } return LengthSetter(); } void main() { auto arr = [ 1, 2, 3 ]; arr.assumedLength = 10; writeln(arr); } Joking aside, I liked the nested struct and its opAssign to mimic internal `arr.length = 42` syntax. (I know it involves a potentially expensive delegate but still...) Ali
Re: Using "strcpy" to assign value to dynamic char array
On Monday, 1 November 2021 at 21:01:31 UTC, Ali Çehreli wrote: On 11/1/21 1:49 PM, pascal111 wrote: > Yes, I'm practicing doing things in low level style like standard C. All you needed extra was to let the slice know about the new length: import std.stdio; import core.stdc.string; void main() { char[] s="xyz".dup; strcpy([0], "Hello World!"); s = s.ptr[0..12]; // <-- Here writeln(s); } Now, the result is "correct" without dup: Hello World! The program is as incorrect as its C equivalent would be. ;) Ali This can serve the style I want. It uses OOP style like C++ by putting a pointer as a property, but pointers themselves are low level.
Re: Using "strcpy" to assign value to dynamic char array
On 11/1/21 1:49 PM, pascal111 wrote: > Yes, I'm practicing doing things in low level style like standard C. All you needed extra was to let the slice know about the new length: import std.stdio; import core.stdc.string; void main() { char[] s="xyz".dup; strcpy([0], "Hello World!"); s = s.ptr[0..12]; // <-- Here writeln(s); } Now, the result is "correct" without dup: Hello World! The program is as incorrect as its C equivalent would be. ;) Ali
Re: Using "strcpy" to assign value to dynamic char array
On Monday, 1 November 2021 at 20:15:14 UTC, Steven Schveighoffer wrote: On 11/1/21 3:56 PM, pascal111 wrote: But what if I want to use "strcpy" function to assign that new value to the array that the problem is that the array won't take more than its first initializing value length: { char[] s="xyz".dup; strcpy([0], "Hello World!"); writeln(s); } Result: Hel Don't do this, you just corrupted memory! You wrote 13 bytes into a memory location that contains 3. Use `.dup`, it does the equivalent of `strcpy`. Can you share why you want to use `strcpy` here? -Steve Yes, I'm practicing doing things in low level style like standard C.
Re: Using "strcpy" to assign value to dynamic char array
On 11/1/21 3:56 PM, pascal111 wrote: But what if I want to use "strcpy" function to assign that new value to the array that the problem is that the array won't take more than its first initializing value length: { char[] s="xyz".dup; strcpy([0], "Hello World!"); writeln(s); } Result: Hel Don't do this, you just corrupted memory! You wrote 13 bytes into a memory location that contains 3. Use `.dup`, it does the equivalent of `strcpy`. Can you share why you want to use `strcpy` here? -Steve
Using "strcpy" to assign value to dynamic char array
I know that I can use the next syntax to assign new value to char dynamic array, and the new value isn't in same length of the current value of the array: { char[] s="xyz".dup; s="Hello World!".dup; writeln(s); } Result: Hello World! = But what if I want to use "strcpy" function to assign that new value to the array that the problem is that the array won't take more than its first initializing value length: { char[] s="xyz".dup; strcpy([0], "Hello World!"); writeln(s); } Result: Hel