How to be more careful about null pointers?
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon Mar 28 23:21:49 PDT 2016
On 03/28/2016 11:00 PM, cy wrote:
> struct Database {
> string derp;
> Statement prepare(string s) {
> return Statement(1234);
> }
> }
>
> struct Statement {
> int member;
> void bind(int column, int value) {
> import std.stdio;
> writeln("derp",member);
Change that to &member and it will not segfault. It will print a value
as low as 20. Your program is thinking that the Statement object is at
address 20. :(
> }
>
> }
>
>
> class Wrapper {
> Database something;
> Statement prep;
> this() {
> something = Database("...");
> prep = something.prepare("...");
> }
> }
>
> Wrapper oops;
> void initialize() {
> oops = new Wrapper();
> }
>
> class Entry {
> Wrapper parent;
> this(Wrapper parent) {
> //this.parent = parent;
> //oops
> parent = parent;
> }
> void usefulmethod() {
> parent.prep.bind(1,42);
parent.prep.bind is translated to the following by the compiler:
"Call bind() for the object at address... let's calculate... Wherever
parent is, we should add the offset of prep inside that object."
Since 'parent' is a class reference, implemented in terms of a CPU
pointer, which happens to be uninitialized, meaning that its value is 0,
the overall address is the following on my machine:
0 + 20
As you've observed, the program never accesses location 0 for 'parent',
rather, calculates the member starting with 'parent' and tries to access
a location inside the first page, which is reserved by the operating
system to catch exactly situations like this.
Ali
More information about the Digitalmars-d-learn
mailing list