digitalmars.D.learn - Access Violation when accessing Dynamic Array
- Jack (30/30) Jan 02 2016 So yeah I've been trying to experiment with the language when I'm
- tsbockman (6/37) Jan 02 2016 Your example does not compile, even after I add the required
- tsbockman (4/5) Jan 02 2016 Also, your sample reads from an external file, "read.txt". Either
- Jack (11/16) Jan 02 2016 Woops, sorry about that. It's about late midnight around here so
So yeah I've been trying to experiment with the language when I'm met with an Access Violation error. So I've extracted a string from a file and used it as an index for a dynamic array. Stripped code sample is : ///////////////////////////// void foo() { string[string] custom; string keyword; string script; File file = File("read.txt", r); while(!file.eof()) { script ~= file.readln(); } foreach(a; script) { keyword ~= a; //assuming keyword is "Mario" } keyword = stripLeft(keyword); custom[keyword] = "sample string"; writeln(keyword); // Outputs "Mario" writeln(custom[keyword]); // Works fine. Outputs "sample string". writeln(custom["Mario"]); // First-chance exception: 0xc0000005: Access violation } ///////////////////////////// So am I doing something wrong here? Did I mess with something that I shouldn't have? If it helps I'm using dmd v.2.069.2 on Win7 64-bit.
Jan 02 2016
On Saturday, 2 January 2016 at 16:48:41 UTC, Jack wrote:So yeah I've been trying to experiment with the language when I'm met with an Access Violation error. So I've extracted a string from a file and used it as an index for a dynamic array. Stripped code sample is : ///////////////////////////// void foo() { string[string] custom; string keyword; string script; File file = File("read.txt", r); while(!file.eof()) { script ~= file.readln(); } foreach(a; script) { keyword ~= a; //assuming keyword is "Mario" } keyword = stripLeft(keyword); custom[keyword] = "sample string"; writeln(keyword); // Outputs "Mario" writeln(custom[keyword]); // Works fine. Outputs "sample string". writeln(custom["Mario"]); // First-chance exception: 0xc0000005: Access violation } ///////////////////////////// So am I doing something wrong here? Did I mess with something that I shouldn't have? If it helps I'm using dmd v.2.069.2 on Win7 64-bit.Your example does not compile, even after I add the required imports (std.algorithm and std.stdio): Error: template std.algorithm.mutation.stripLeft cannot deduce function from argument types !()(string) Please test your example code before asking for help.
Jan 02 2016
On Saturday, 2 January 2016 at 16:48:41 UTC, Jack wrote:[...]Also, your sample reads from an external file, "read.txt". Either give us the contents of that file, or change the sample so that it is not required.
Jan 02 2016
On Saturday, 2 January 2016 at 17:15:53 UTC, tsbockman wrote:On Saturday, 2 January 2016 at 16:48:41 UTC, Jack wrote:Woops, sorry about that. It's about late midnight around here so I didn't really notice. I can't seem to replicate the problem with the dumbed down example(ironic yes). So I'll just send the whole file if you don't mind: http://dpaste.com/11V5BYA (Line 174-183) The contents of the .txt file is : http://dpaste.com/3FVW5QR I just checked it and it compiles but it does that strange Access Violation error.[...]Also, your sample reads from an external file, "read.txt". Either give us the contents of that file, or change the sample so that it is not required.
Jan 02 2016
On Saturday, 2 January 2016 at 17:39:42 UTC, Jack wrote:So I'll just send the whole file if you don't mind: http://dpaste.com/11V5BYA (Line 174-183) The contents of the .txt file is : http://dpaste.com/3FVW5QR I just checked it and it compiles but it does that strange Access Violation error.By far the most likely explanation for an exception at that location, would be if `custom_keyword` really didn't contain a valid key into the `custom` associative array. So, to check I added this code: writefln("custom_keyword: \"%s\"", custom_keyword); stdout.flush(); // This may be required if you're running the code inside an IDE. readln(); Right before `custom[custom_keyword]`. This printed the following: custom_keyword: "Mario " Notice the extra space at the end. The solution is to use `strip()` rather than `stripLeft()`.
Jan 02 2016
On Saturday, 2 January 2016 at 17:56:12 UTC, tsbockman wrote:On Saturday, 2 January 2016 at 17:39:42 UTC, Jack wrote:Thank you! I can't believe I haven't noticed the whitespace. I should stop staying up late at night.[...]By far the most likely explanation for an exception at that location, would be if `custom_keyword` really didn't contain a valid key into the `custom` associative array. So, to check I added this code: writefln("custom_keyword: \"%s\"", custom_keyword); stdout.flush(); // This may be required if you're running the code inside an IDE. readln(); Right before `custom[custom_keyword]`. This printed the following: custom_keyword: "Mario " Notice the extra space at the end. The solution is to use `strip()` rather than `stripLeft()`.
Jan 02 2016
On Saturday, 2 January 2016 at 17:39:42 UTC, Jack wrote:So I'll just send the whole file if you don't mind: http://dpaste.com/11V5BYA (Line 174-183) The contents of the .txt file is : http://dpaste.com/3FVW5QRI didn't put a lot of effort into trying to actually understand what you're doing, but a couple of other issues that jumped out at me were: 1) You don't need to use `cmp` to compare strings - this isn't Java :) Just use `==` directly - in D this will compare the strings by value, not reference. (If you actually need to compare by reference, you can use `is` or compare the `.ptr` properties.) 2) `if(some_bool == true)` is redundant - just write `if(some_bool)`. Similarly, `if(some_bool == false)` can be shortened to `if(! some_bool)`. 3) Currently, there is no reason for `flags` to be an associative array; it could be replaced by a simple list of variables: bool keyword = false, initialize = false, gameObject_init = false, movement = false, playMusic = false, playSound = false; This would be *much* faster than doing an associative array lookup for every single character in `script`. 4) The value type for the string[string] fields symbol, symbol_init, and keywords could be changed to custom `enum` types, instead of `string`, which would again be much faster.
Jan 02 2016
On Saturday, 2 January 2016 at 18:14:24 UTC, tsbockman wrote:On Saturday, 2 January 2016 at 17:39:42 UTC, Jack wrote:I didn't actually knew it works that way because last time I tried using '==' directly it won't compare.So I'll just send the whole file if you don't mind: http://dpaste.com/11V5BYA (Line 174-183) The contents of the .txt file is : http://dpaste.com/3FVW5QRI didn't put a lot of effort into trying to actually understand what you're doing, but a couple of other issues that jumped out at me were: 1) You don't need to use `cmp` to compare strings - this isn't Java :) Just use `==` directly - in D this will compare the strings by value, not reference. (If you actually need to compare by reference, you can use `is` or compare the `.ptr` properties.)2) `if(some_bool == true)` is redundant - just write `if(some_bool)`. Similarly, `if(some_bool == false)` can be shortened to `if(! some_bool)`.Yeah I did that in a panic attempt to fix the problem.3) Currently, there is no reason for `flags` to be an associative array; it could be replaced by a simple list of variables: bool keyword = false, initialize = false, gameObject_init = false, movement = false, playMusic = false, playSound = false; This would be *much* faster than doing an associative array lookup for every single character in `script`.I always thought that associative arrays are much more faster and more clean than this. Thanks I'll keep that in mind4) The value type for the string[string] fields symbol, symbol_init, and keywords could be changed to custom `enum` types, instead of `string`, which would again be much faster.And this is news to me too. I'll keep enums in mind. Overall thank you for your help and advice. I'll seriously keep these in mind.
Jan 02 2016
On Sunday, 3 January 2016 at 03:41:12 UTC, Jack wrote:I didn't actually knew it works that way because last time I tried using '==' directly it won't compare.Well, there are always many ways that things can go wrong (including compiler bugs), but it SHOULD work, so ask on the forums if it doesn't.Yeah I did that in a panic attempt to fix the problem.Ah yes. I've been there before, myself...I always thought that associative arrays are much more faster and more clean than this. Thanks I'll keep that in mindThe associative array itself is quite fast, as long as the data set doesn't have too many hash collisions. But, the lookup as a whole is limited by the speed of the key type's hash code function, and of its comparison function. For, say, an integer, both the hash code and the comparison can be accomplished with about two instructions. Thus, a value_type[int] array would be very fast. However, you are using `string` values as the keys, which means that getting the hash code or doing a comparison involves looping over each character in the `string`. Obviously this is going to be slower. This is not to say it's actually *slow* - don't feel bad about using an associative array with `string` keys if that's really what you need. (And you're likely to need one for *something* since you're writing a parser.) Assuming all the key values (variable names) are known at compile time, using boolean variables directly like I suggested is (nearly) the fastest method possible, because the `string` lookup is done during compilation, and is translated into a simple memory access or register access in the generated assembly code.And this is news to me too. I'll keep enums in mind. Overall thank you for your help and advice. I'll seriously keep these in mind.You're welcome.
Jan 03 2016