memory trampling

J

joshuajnoble

Apologies in advance if I don't provide adequate details on this
problem. I have a kind of chimp-like understanding that my approach
is
wrong, but I don't understand exactly why it's off and I'm looking
for
some help. I have a library that I'm linking to that takes pointers
to
a particular kind of obj and adds them a processing thread.
AddObj(A* aPtr)
I'm making a library for people to use that thread without needing to
know a ton about the implementation details of that, they should be
able to just make a simple friendly type, say WrapperA and call
initialize on it.
WrapperA wa;
.....
wa.init(2500, SINE, 100, 1.f);
WrapperA holds an actual A*, which it then instantiates and passes to
the AddObj method, so:
void WrapperA::init(int length, int order, double coefs, float range)
{
ASubClass* (a) = new ASubClass(length, order, coefs, range);
Delegate::getInstance()->addObject( (A *)a );
}

My singleton there has the actual thread object, so it just gets the
pointer and adds it to the thread:
void Delegate::addObject(A* obj)
{
thread.AddObj(obj);
}

That causes a EXEC_BAD_ACCESS when the thread actually does its
processing because the memory is getting trampled and I GDB can't
reconstrcut the frame:
previous frame inner to this frame (corrupt stack?)
Now, I'm not super savvy on what exacty the thread does with that
memory, but I've played around with it a lot outside of my little
wrapper library scheme and it works fine, so the problem is in my
implementation. I'm thinking my whole "make this thing friendly for
the non-pointer savvy" is a little silly, and I'm probably going to
scrap it, but I'd like to understand why the memory is getting
tramped
here (if that is what is in fact happening). Thanks and I'd be happy
to provide more details if there's something important I haven't
provided.

josh
 
Z

Zeppe

joshuajnoble said:
That causes a EXEC_BAD_ACCESS when the thread actually does its
processing because the memory is getting trampled and I GDB can't
reconstrcut the frame:
previous frame inner to this frame (corrupt stack?)
Now, I'm not super savvy on what exacty the thread does with that
memory, but I've played around with it a lot outside of my little
wrapper library scheme and it works fine, so the problem is in my
implementation.

You say that without "wrapping" the creation of obj within the WrapperA
constructor and calling the delegate everything works fine. Since I
cannot see any obvious error in that code, I try to guess: may it be a
problem of static initialisation order? When do you call the Wrapper::init?

And, if your Delegate is built at the program initialisation, are you
sure that the thread object, if not built within the delegate, is
already there?

Best wishes,

Zeppe
 
J

joshuajnoble

joshuajnoblewrote:

You say that without "wrapping" the creation of obj within the WrapperA
constructor and calling the delegate everything works fine. Since I
cannot see any obvious error in that code, I try to guess: may it be a
problem of static initialisation order? When do you call the Wrapper::init?

And, if your Delegate is built at the program initialisation, are you
sure that the thread object, if not built within the delegate, is
already there?

Best wishes,

Zeppe


I threw together a quick test here, I'm thinking my problem is in what
I'm doing with the static pointer (perhaps). Here's my Singleton:


#ifndef SINGLETON
#define SINGLETON

class SingletonImpl
{
public:
static SingletonImpl* getInst();
int val1;
char* val2[5];

protected:
static SingletonImpl* inst;
SingletonImpl();

};

#endif

SingletonImpl::SingletonImpl(){
val1 = 1;
val2 = "abcdefghijklmn";
}

SingletonImpl* SingletonImpl::getInst(){
if(inst == 0) {
inst = new SingletonImpl();
}
return inst;
}

And then I have some objects that I need to have access the singleton
in their constructors:


#include "TestObjs.h"

TestObjs::TestObjs(char* ch){
c = ch;
SingletonImpl::getInst()->val2[0] = c;
}

class TestObjs {
public:
TestObjs(char* ch);
char* c;
};


And then my main:

int main (int argc, char * const argv[]) {
char* c = "ghu";
TestObjs t = TestObjs(c);
char* c3 = "3333333";
TestObjs t2 = TestObjs(c3);
return 0;
}

And this blows up...I realize this is a pretty rudimentary question
and not really on par with the normal level of discussion here so
thanks in advance for any help and your patience :)
 
Z

Zeppe

joshuajnoble said:
I threw together a quick test here, I'm thinking my problem is in what
I'm doing with the static pointer (perhaps). Here's my Singleton:

I'm not sure, I can't see major problems in this piece of code.
#ifndef SINGLETON
#define SINGLETON

class SingletonImpl
{
public:
static SingletonImpl* getInst();
int val1;
char* val2[5];

protected:
static SingletonImpl* inst;
SingletonImpl();

};

#endif

SingletonImpl::SingletonImpl(){
val1 = 1;
val2 = "abcdefghijklmn";

this is maybe val2[0] = "..."; otherwise, it won't compile. However, it
will give you warning anyway regarding the conversion from const char*
(the string literal) to char*.
}

SingletonImpl* SingletonImpl::getInst(){
if(inst == 0) {
inst = new SingletonImpl();
}
return inst;
}

Surely inst is initialised somewhere to NULL, as in

SingletonImpl* SingletonImpl::inst = NULL;

or similar. Otherwise it won't link. If you don't initialise it to zero,
it will compile and crash.

TestObjs::TestObjs(char* ch){
c = ch;
SingletonImpl::getInst()->val2[0] = c;
}

class TestObjs {
public:
TestObjs(char* ch);
char* c;
};


And then my main:

int main (int argc, char * const argv[]) {
char* c = "ghu";
TestObjs t = TestObjs(c);
char* c3 = "3333333";
TestObjs t2 = TestObjs(c3);
return 0;
}

again, only the deprecated casts from string literal to char* seem "wrong".
And this blows up...I realize this is a pretty rudimentary question
and not really on par with the normal level of discussion here so
thanks in advance for any help and your patience :)

I don't think so, really. Araprt from the fact that the level here gets
very low at times, every question is worth discussing. Check the
SingletonImpl::inst initialisation, and if it is all right, in my
opinion it should not crash, so you may want to post the complete code
that in your pc generates the error.

Best wishes,

Zeppe
 
J

James Kanze

On Oct 20, 12:03 pm, Zeppe

[...]
I threw together a quick test here, I'm thinking my problem is
in what I'm doing with the static pointer (perhaps). Here's my
Singleton:

This isn't the actual code, since it won't compile...
#ifndef SINGLETON
#define SINGLETON

class SingletonImpl
{
public:
        static SingletonImpl* getInst();
        int val1;
        char* val2[5];

protected:
                static SingletonImpl* inst;
                SingletonImpl();
};

#endif

SingletonImpl::SingletonImpl(){
        val1 = 1;
        val2 = "abcdefghijklmn";

since this statement is illegal.
}

SingletonImpl* SingletonImpl::getInst(){
        if(inst == 0) {
                inst = new SingletonImpl();
        }
        return inst;
}
And then I have some objects that I need to have access the
singleton in their constructors:
#include "TestObjs.h"
TestObjs::TestObjs(char* ch){
        c = ch;
        SingletonImpl::getInst()->val2[0] = c;

}
class TestObjs {
public:
        TestObjs(char* ch);
        char* c;
};
And then my main:
int main (int argc, char * const argv[]) {
        char* c = "ghu";
    TestObjs t = TestObjs(c);
        char* c3 = "3333333";
    TestObjs t2 = TestObjs(c3);
        return 0;
}

There's also the problem that you never defined
SingletonImpl::inst. Which means undefined behavior---on my
machine, it won't link.
And this blows up...

It doesn't compile, so it can't blow up. What else did you
change when posting, which might be hiding the problem? (The
basic singleton management seems perfectly correct, modulo the
missing data definition. So the problem has to do with
something you've accidentally changed, in the same way you
accidentally changed something which made it illegal, or with
the undefined behavior because of the missing definition of
SingletonImpl::impl---maybe your compiler provides it
implicitly, but doesn't zero initialize it.)
 
J

James Kanze

I'm not sure, I can't see major problems in this piece of code.

[...]
this is maybe val2[0] = "..."; otherwise, it won't compile.

I'd count that as a major problem, since it means that he's not
posting the actual code which causes the problem.
However, it will give you warning anyway regarding the
conversion from const char* (the string literal) to char*.

The standard doesn't require warnings:). As a quality of
implementation issue, of course, a good compiler should give the
warning. Provided you've invoked it as a good C++
compiler---every compiler I know needs a half a dozen options to
be truly a C++ compiler.

[...]
Surely inst is initialised somewhere to NULL, as in
SingletonImpl* SingletonImpl::inst = NULL;
or similar. Otherwise it won't link.

You don't actually need the initialization, since objects with
static lifetime are zero initialized anyway. But without the
definition, it's undefined behavior---with the compilers I
usually use, it won't link either, but the standard doesn't
require an error of any sort, and it's quite possible that a
compiler could implicitly supply the definition, but skip the
zero initialization for it. That would still be conforming (but
not really what I would call a very good implementation).
 

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

Forum statistics

Threads
473,707
Messages
2,569,343
Members
44,635
Latest member
Matt231

Latest Threads

Top