digitalmars.D.learn - Can't understand if deallocation happens?
- Suliman (41/42) Jan 22 2017 import std.stdio;
- Nicholas Wilson (4/46) Jan 22 2017 You do not append to anything, only overwrite it. There is no
- Suliman (5/8) Jan 22 2017 I changed my code to:
- Adam D. Ruppe (6/7) Jan 22 2017 That means copy the contents of the right hand array into the
- Adam D. Ruppe (14/20) Jan 22 2017 You freed the CONTENTS, but are printing the CONTAINER.
- Suliman (28/31) Jan 22 2017 So str.ptr is just shortcut?
- Adam D. Ruppe (17/23) Jan 22 2017 str.ptr is the actual member. In D, pointers to structs (and an
- Suliman (7/20) Jan 22 2017 string str = "aaa";
- Suliman (9/9) Jan 22 2017 string str = "abc";
- Suliman (7/16) Jan 22 2017 writeln("old data: ", cast(int)*(str.ptr-1));
- Mike Parker (7/24) Jan 22 2017 You have *two* distinct strings here. Why do you expect them to
- Suliman (2/3) Jan 22 2017 Yes, I understand, I am trying to find out how it's work on low
- Nicholas Wilson (8/11) Jan 22 2017 string *literals* in d are nul terminated to ease interoperation
import std.stdio; import std.string; import core.memory; void main() { char [] str = "aaa".dup; char [] *str_ptr = &str; writeln("before: ", str_ptr.ptr);// address of structure writeln(*str_ptr.ptr); // address of data str[] = "bbb"[]; // now writing to structure new data, so ptr would be point to them writeln("after: ", str_ptr.ptr); writeln("length: ", str_ptr.length); writeln("str_ptr point to: ", *str_ptr.ptr); writeln(str_ptr); writeln("before dealloc: ", str_ptr.length); GC.free(str_ptr.ptr); writeln(str_ptr); writeln("after dealloc: ", str_ptr.length); } As I understand str structure would have 2 data peace after writing "bbb" to it. But ptr will point to last one (to "bbb"). [aaa] [bbb] --------+ So after appending "bbb" I should see that the size is 3, after appending 6. After GC again 3. But I see only 3 before and after GC:app.exebefore: 2641010 a after: 2641010 length: 3 str_ptr point to: b 19FE0C before dealloc: 3 19FE0C after dealloc: 3 And am I right understand that here memory should be GC-ed? Another question: writeln("before: ", str_ptr.ptr);// address of structure Is it's address from 0 of current App memory?
Jan 22 2017
On Sunday, 22 January 2017 at 12:49:11 UTC, Suliman wrote:import std.stdio; import std.string; import core.memory; void main() { char [] str = "aaa".dup; char [] *str_ptr = &str; writeln("before: ", str_ptr.ptr);// address of structure writeln(*str_ptr.ptr); // address of data str[] = "bbb"[]; // now writing to structure new data, so ptr would be point to them writeln("after: ", str_ptr.ptr); writeln("length: ", str_ptr.length); writeln("str_ptr point to: ", *str_ptr.ptr); writeln(str_ptr); writeln("before dealloc: ", str_ptr.length); GC.free(str_ptr.ptr); writeln(str_ptr); writeln("after dealloc: ", str_ptr.length); } As I understand str structure would have 2 data peace after writing "bbb" to it. But ptr will point to last one (to "bbb"). [aaa] [bbb] --------+ So after appendingYou do not append to anything, only overwrite it. There is no reallocation because "aaa".length == "bbb".length."bbb" I should see that the size is 3, after appending 6. After GC again 3. But I see only 3 before and after GC:app.exebefore: 2641010 a after: 2641010 length: 3 str_ptr point to: b 19FE0C before dealloc: 3 19FE0C after dealloc: 3 And am I right understand that here memory should be GC-ed? Another question: writeln("before: ", str_ptr.ptr);// address of structure Is it's address from 0 of current App memory?
Jan 22 2017
You do not append to anything, only overwrite it. There is no reallocation because "aaa".length == "bbb".length.I changed my code to: str_ptr.length +=1; str[] = "bbbb"[]; But now it's print length 4 before and after writing "bbb" to `str`. I expected that size will be 3+4=7.
Jan 22 2017
On Sunday, 22 January 2017 at 13:34:10 UTC, Suliman wrote:str[] = "bbbb"[];That means copy the contents of the right hand array into the location of the left hand array. It copies data, that operation will never change pointers. str = "bbbb"; would change the pointer.
Jan 22 2017
On Sunday, 22 January 2017 at 12:49:11 UTC, Suliman wrote:writeln(str_ptr); writeln("before dealloc: ", str_ptr.length); GC.free(str_ptr.ptr); writeln(str_ptr);You freed the CONTENTS, but are printing the CONTAINER. str_ptr.ptr returns exactly the same thing as str.ptr or (*str_ptr).ptr, a pointer to the contents. When you write str_ptr, you print the pointer to the container. The container isn't moving, it is a stack variable and not managed by GC. If you want to see changes to the content pointer, just use it. string* in D is rarely what you want and I suggest you avoid using it until you have a strong grasp on the fundamentals of how arrays and pointers work. You're just confusing yourself by trying it right now.Is it's address from 0 of current App memory?it is the virtual address space, the app doesn't necessarily use all the possible values.
Jan 22 2017
str_ptr.ptr returns exactly the same thing as str.ptr or (*str_ptr).ptr, a pointer to the contents. When you write str_ptr, you print the pointer to the container.So str.ptr is just shortcut? Ok, but how to free memory from first located value (from `aaa`)? I changed my code to next: import std.stdio; import std.string; import core.memory; void main() { string str = "aaa".dup; string *str_ptr = &str; writeln("before: ", str_ptr.ptr);// address of structure writeln(*str_ptr.ptr); // address of data str = "bbbb"; // now writing to structure new data, so ptr would be point to them writeln("after: ", str_ptr.ptr); writeln("length: ", str_ptr.length); writeln("str_ptr point to: ", *str_ptr.ptr); writeln(str_ptr); writeln("before dealloc: ", str_ptr.length); //GC.free(str_ptr.ptr); // Error: function core.memory.GC.free (void* p) is not callable using argument types (immutable(char)*) writeln(str_ptr); writeln("after dealloc: ", str_ptr.length); } But I can't call `GC.free(str_ptr.ptr)` on string type, only on `char []`
Jan 22 2017
On Sunday, 22 January 2017 at 14:04:55 UTC, Suliman wrote:So str.ptr is just shortcut?str.ptr is the actual member. In D, pointers to structs (and an array is virtually the same as a struct) will automatically dereference themselves. T* t; t.member; // automatically rewritten into (*t).member) Your str_ptr variable in this code is completely useless and should be removed. It's presence only confuses you.Ok, but how to free memory from first located value (from `aaa`)?Supported answer: you don't, it has infinite lifetime and you're claiming it is immutable, but then trying to pull the memory out from under it! The supported solution is simply to let the garbage collector manage it. But..//GC.free(str_ptr.ptr); // Error: function core.memory.GC.free (void* p) is not callable using argument types (immutable(char)*)If you must call the function though, you can simply `cast(void*) str.ptr`, or use `char[]` up above instead of `string` when declaring it, so it has a mutable pointer to begin with. Since you are using .dup anyway, both declarations are equally legal.
Jan 22 2017
Supported answer: you don't, it has infinite lifetime and you're claiming it is immutable, but then trying to pull the memory out from under it! The supported solution is simply to let the garbage collector manage it. But..string str = "aaa"; writeln(str.length); // print 3 str = "bbbb"; writeln(str.length); //print 4 expected 3+4=7 [aaa][bbbb] (2 blocks) GC.free(cast(void*) str.ptr); writeln(str.length); //print 4//GC.free(str_ptr.ptr); // Error: function core.memory.GC.free (void* p) is not callable using argument types (immutable(char)*)If you must call the function though, you can simply `cast(void*) str.ptr`, or use `char[]` up above instead of `string` when declaring it, so it has a mutable pointer to begin with. Since you are using .dup anyway, both declarations are equally legal.
Jan 22 2017
string str = "abc"; writeln(str.ptr); str = "def"; writeln("last data: ", *(str.ptr)); writeln("old data: ", *(str.ptr-1)); // print nothing writeln("old data: ", *(str.ptr-2)); // print c It's look like that there is some gap between data, because `d` minus 1 should be `c`, but `c` I am getting only if I am doing `-2`. Why?
Jan 22 2017
On Sunday, 22 January 2017 at 15:51:01 UTC, Suliman wrote:string str = "abc"; writeln(str.ptr); str = "def"; writeln("last data: ", *(str.ptr)); writeln("old data: ", *(str.ptr-1)); // print nothing writeln("old data: ", *(str.ptr-2)); // print c It's look like that there is some gap between data, because `d` minus 1 should be `c`, but `c` I am getting only if I am doing `-2`. Why?writeln("old data: ", cast(int)*(str.ptr-1)); #old data: 0 String is gaping by zero?? I thought they are continuously like abcdef ---↑ Where `↑` is equal to `ptr`.
Jan 22 2017
On Sunday, 22 January 2017 at 15:59:47 UTC, Suliman wrote:On Sunday, 22 January 2017 at 15:51:01 UTC, Suliman wrote:You have *two* distinct strings here. Why do you expect them to be sequential in memory? If you want them to be treated as one string, concatenate them. auto s1 = "abc"; auto s2 = "def"; auto s3 = s1 ~ s2;string str = "abc"; writeln(str.ptr); str = "def"; writeln("last data: ", *(str.ptr)); writeln("old data: ", *(str.ptr-1)); // print nothing writeln("old data: ", *(str.ptr-2)); // print c It's look like that there is some gap between data, because `d` minus 1 should be `c`, but `c` I am getting only if I am doing `-2`. Why?writeln("old data: ", cast(int)*(str.ptr-1)); #old data: 0 String is gaping by zero?? I thought they are continuously like abcdef ---↑ Where `↑` is equal to `ptr`.
Jan 22 2017
You have *two* distinct strings here.Yes, I understand, I am trying to find out how it's work on low level. Any ideas why zero is used?
Jan 22 2017
On Monday, 23 January 2017 at 06:42:00 UTC, Suliman wrote:string *literals* in d are nul terminated to ease interoperation with C so string s = "foo"; writefln("%d",cast(ubyte)s.ptr[3]); // use '.ptr' to skip bounds check prints 0uYou have *two* distinct strings here.Yes, I understand, I am trying to find out how it's work on low level. Any ideas why zero is used?
Jan 22 2017