www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - SIGSEGV (Segmentation Fault) upon setting character in char array

reply John Kiro <johnkirollos gmail.com> writes:
Hello there,

First time to experiment with DLang, after a long time.

I'm getting a weird behavior with an **array of chars**, where I 
get a segmentation fault upon writing to it (see code and output 
below). What makes this problem weird it two things:

1) Why there is no problem with the **int** array (unlike the 
**char** array)?
2) Why reading the array element (**charArray[index]**) works, 
unlike writing to it?

The problem is gone if I uncomment the constructor code.

Code:

      import std.stdio;

      void main()
      {
        (new Test).runit();
      }

      class Test {
        static enum MAX = 10;
        uint index = 0;
        auto intArray = new int[MAX];
        auto charArray = new char[MAX];

        this() {
          /*
          charArray = new char[MAX];
          */
        }

        void runit() {
          debug writefln("IntArray initially: %s", intArray);
          intArray[index] = 40; //OK
          debug writefln("IntArray becomes: %s", intArray);

          debug writefln("Adding char in place of (%c) at index 
(%d)..",
                         charArray[index], index);
          charArray[index] = 'a'; //ERROR: segmentation fault 
(code -11)!
          debug writefln("CharArray becomes %s (PROGRAM ABORTS 
BEFORE IT ACTUALLY!)",
                        charArray);
        }
      }


Output:

      $ dub run
          Starting Performing "debug" build using 
/home/john/dlang/dmd-2.106.0/linux/bin64/dmd for x86_64.
          Building hello-dlang ~master: building configuration 
[application]
           Linking hello-dlang
           Running hello-dlang
      IntArray initially: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
      IntArray becomes: [40, 0, 0, 0, 0, 0, 0, 0, 0, 0]
      Adding char in place of (�) at index (0)..
      Error Program exited with code -11
Dec 19 2023
parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Tuesday, 19 December 2023 at 13:10:40 UTC, John Kiro wrote:
      class Test {
        static enum MAX = 10;
        uint index = 0;
        auto intArray = new int[MAX];
        auto charArray = new char[MAX];
This is run at compile time, and the compiler treats any char array at compile time as an immutable string literal when it crosses the barrier into run time. Moreover, this would be a static instance of the initial array; the default reference is shared across all objects created (so if you modify intArray then `new` another object, you'll see the modified intArray!). You almost never want to assign arrays or objects at compile time like this in a class definition; use constructors instead. I think the `new char[]` thing being immutable in runtime is a compiler bug, it makes it immutable but it is still typed as mutable in the type system. but this whole static init thing is probably not what you want anyway.
Dec 19 2023
parent reply John Kiro <johnkirollos gmail.com> writes:
Thanks Adam. I agree, the behavior associated with the 
initialization here is confusing (compared for example to a 
similarly-looking code in Java). Also I don't get why an array of 
characters would be considered as an immutable array of 
characters (that is a **string**). I agree this could be a 
compiler bug, specially that it's not caught by the compiler.
Dec 19 2023
parent John Kiro <johnkirollos gmail.com> writes:
On Tuesday, 19 December 2023 at 14:01:31 UTC, John Kiro wrote:
 Thanks Adam. I agree, the behavior associated with the 
 initialization here is confusing (compared for example to a 
 similarly-looking code in Java). Also I don't get why an array 
 of characters would be considered as an immutable array of 
 characters (that is a **string**). I agree this could be a 
 compiler bug, specially that it's not caught by the compiler.
I mean: specially that **attempting to update it** is not caught by the compiler.
Dec 19 2023