Strange pointer replication

Z

Zapanaz

I had a problem which stumped me for hours ... I still don't get how I
solved it.

First I have an application class, let's call it MyApp. This is the
central class in this program.

As MyApp starts up, it establishes a connection to a Sqlite database
which returns a pointer, this pointer is then used in all subsequent
database calls. However, for my purposes here, I -think- this pointer
can just be thought of as a 'generic' pointer. (That might be wrong
though, and that might be the heart of my problem.)

So in MyApp, I have a

sqlite3 * db = StartUpSqlite();

Next I have a class which is basically a window, MyWindow. MyApp
instantiates a MyWindow. MyWindow has a pointer to the parent app,

MyApp * parentApp

And MyApp sets MyWindow.parentApp to 'this' ('this' being the MyApp
instance).

MyWindow has a member of class DBView, you pass in a SQL query and
DBView displays the results in a table layout. First though DBView
has to have the database pointer. So DBView has a method

SetDb(sqlite * inputDb)

And MyWindow calls this with

SetDb(parentApp->db)

DBView has a member

sqlite * db

And SetDb simply does

db = inputDb

Anyway, so far so good ... the parent app establishes the DB
connection, gets the pointer (which is just a number, albeit to the
compiler a number with a definite context and characteristics), passes
it to the window, and the window passes it to the DB view.

And so far everything works as expected, when DBView does a query
using the DB pointer, it works as expected.

Later I am doing a query which will only work if it is executed using
the same DB pointer which was used at an earlier part of the program
(within MyApp). I don't want to make this complicated ... basically,
in MyApp I define a custom DB function. That custom function is only
visible to the DB pointer that was used to create it.

This seems like it should be no problem though. The DB pointer is
just a number? It's created when I connect to the DB, I only connect
to the DB once in the whole program, so it seems like I -couldn't- use
the "wrong" DB pointer.

But when I try to use the custom function (the one which will only
work with the DB pointer which was used to create it) it fails.

So anyway I spend hours trying to figure out what's wrong, it doesn't
even cross my mind that I could be using the wrong DB pointer, for the
reasons above.

Finally I look closely at what's going on in a debugger, note the
value of the DB pointer in MyApp, then look at the value of
parentApp->db in MyWindow when it's doing

dbView.SetDb(parentApp->db)

And they're totally different. I mean, both in MyApp when I look at
MyApp.db, and in MyWindow when I look at parentApp->db, in both cases
I should be looking at just a memory address, the address pointed to
by the DB pointer?

So then in MyApp, when I create MyWindow, and set

MyWindow.parentApp = this

I also set a new member of MyWindow, sqlite * db,

MyWindow.db = db

Really I just did this to make things more clear when I was debugging.
But now, when I call

dbView.SetDb(this->db)

The value of db is the same as it is in MyApp, and the custom function
works correctly.

I really don't get this at all.

1. It seems like I somehow accidentally evoked a copy constructor or
something ... but that isn't even possible with a pointer, is it? The
database system, sqlite, is not generally very object-oriented at all
anyway. Conceivably though, somewhere when I was assigning the db
pointer (which is basically a db 'handle', it represents a connection
to the db) it could have created a copy, instead of just copying the
number, which is a memory address. But, as I say, I don't see how
that's possible with a pointer.

2. Maybe there is something just flat-out wrong with my syntax, like
I referenced a pointer to a pointer when I thought I was referencing a
pointer. That would explain how the actual memory value of the
pointer was different in the two locations at run time. But I don't
think the compiler would have missed that. And I don't see it in my
code ... what I have above is essentially what is in my code.

And if that was the case, the db pointer would have essentially a
random value in it. It seems like that should have just failed.
Without knowing more about the internals of the database system I
can't say that for sure ... possibly, since I already have a
connection to the database system from my application, when it got a
bad value, it "covered up" for my mistake and used the existing
connection. But that doesn't really make sense either, because if it
used the correct connection, it should have been aware of the custom
function. Again, without knowing more about the internals, it's hard
to say. (Maybe it just compares the db pointer value to the one used
to create the custom function, but "covers up" the mistake when it
comes to executing queries ... which is all very weird, but I can't
say for sure that isn't what's happening.)

But overall, it seems like the likeliest thing is that creating a copy
of the pointer is somehow the correct c/c++ behavior in some way I'm
not aware of. (It's usually best to look for the simplest, stupidest
explanation for an error ...) But I really don't get why it would do
that.

So, C++ experts ... am I missing something obvious here?




--
Joe Cosby
http://joecosby.com/
"La Cucaracha, la Cucaracha,
Ya no puede caminar,
Porque no tiene, porque le falta,
Marijuana que fumar."

:: Currently listening to Second Dance: Dance Of The Trees, Assai moderato, 1916, by Bartók, from "Cantata Profana/The Wooden Prince"
 
G

Gianni Mariani

Zapanaz wrote:
......
1. It seems like I somehow accidentally evoked a copy constructor or
something ... but that isn't even possible with a pointer, is it?
No.

... The
database system, sqlite, is not generally very object-oriented at all
anyway. Conceivably though, somewhere when I was assigning the db
pointer (which is basically a db 'handle', it represents a connection
to the db) it could have created a copy, instead of just copying the
number, which is a memory address. But, as I say, I don't see how
that's possible with a pointer.

Have you considered that the memory might be trashed somehow ? Run
valgrind or see more closely how it fails.
2. Maybe there is something just flat-out wrong with my syntax, like
I referenced a pointer to a pointer when I thought I was referencing a
pointer. That would explain how the actual memory value of the
pointer was different in the two locations at run time. But I don't
think the compiler would have missed that. And I don't see it in my
code ... what I have above is essentially what is in my code.

Nope - the pointers need to be identical. Sounds like memory
corruption. Perhaps you're reading deleted memory.
And if that was the case, the db pointer would have essentially a
random value in it. It seems like that should have just failed.
Without knowing more about the internals of the database system I
can't say that for sure ... possibly, since I already have a
connection to the database system from my application, when it got a
bad value, it "covered up" for my mistake and used the existing
connection. But that doesn't really make sense either, because if it
used the correct connection, it should have been aware of the custom
function. Again, without knowing more about the internals, it's hard
to say. (Maybe it just compares the db pointer value to the one used
to create the custom function, but "covers up" the mistake when it
comes to executing queries ... which is all very weird, but I can't
say for sure that isn't what's happening.)

But overall, it seems like the likeliest thing is that creating a copy
of the pointer is somehow the correct c/c++ behavior in some way I'm
not aware of. (It's usually best to look for the simplest, stupidest
explanation for an error ...) But I really don't get why it would do
that.

So, C++ experts ... am I missing something obvious here?

No - sounds like memory corruption.
 
C

Christopher Swiedler

What is the new (incorrect) value of the pointer? Does it look like a
valid address? e.g. on Linux you get addresses around 0x8000xxxx for
the heap and 0xffffxxxx for the stack. If the new pointer value is
something totally unlike other pointer values in your app, then it's a
good chance you have memory corruption. Take the pointer value and
convert it to other values (integer, char[], etc) to see if any of
them make sense. Perhaps you ran off the end of a buffer, or re-used
an address you shouldn't have. Is it a really low 4-byte number like
0x00000010? Or, could it be a low integer number that's shifted by 1-4
bytes? Look at the memory around the pointer (not the address that it
points to) and see what data comes before and after it.

chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,108
Latest member
AlbertEste
Top