I've defined in my foo.h the following variables
#define APILONG long
#define APIDOUBLE double
#define APISTRING const char*
And also the following struct
struct SetupData
{
APISTRING customerName;
APIDOUBLE quantity;
APILONG startDate;
};
Now, in my foo.cpp i have the following method where I need to assign values to the members of the struct that are being pulled from a .config file.
APILONG doSomething(APISTRING* setupOrder, APILONG* setupActive, struct SetupData** setupData)
{
//load config file
Config config("rommel.config");
//assign a string value to APISTRING* (No issue here.)
*setupOrder= config.pString("setupOrder").c_str();
//assign a value (No issue here, atleast not that I know of..)
*setupActive = config.pDouble("setupActive");
//assign values to members of struct**
(*setupData)->customerName = config.pString("setupDataCustomerName").c_str();
(*setupData)->quantity = config.pDouble("setupDataQuantity");
(*setupData)->startDate = config.pDouble("setupDataStartDate");
//do other stuff..
}
When I compile and rebuild it does not give me any error messages. But when I try to run the actual program it crashes. (Am using Dev-C++, Visual Studio was causing problems..)
I do however get a chance to see the values assigned before it crashes and it looks like the values are not being assigned (Null or strange characters).
I've tried variations of the
(*setupData)->startDate ..
line and also I have tried declaring the struct in the method like the following, but to no avail.
struct SetupData stpData;
*setupData = &stpData;
Any help would be greatly appreciated. I previously posted another question which is related to this, it contains some pretty useful information aswell. I'll leave the link in case it helps. "C++ Set value for a char**"
The config object is local to the doSomething function.
The setupOrder pointer points to what appears to be a
member of the config object.
The config object will go out of scope at the end of the doSomething function and can be de-allocated at that point.
At that point, what the setupOrder pointer "points" to
might no longer be valid.
It is a good idea to make sure that after the call to doSomething ends,
that all the pointers still point to objects that still exist.
You may have already done this, but I just wanted to check.
Related
I've a problem in my program. I'm getting a exception that crashes the program. Firstly, i innitialize my struct object in my class header. Like so:
struct Settings {
DWORD AccesibilityMode;
bool Raw;
DWORD Type;
};
Settings * thread_settings = new Settings(); //Here im getting the pointer of the newly created
object
Now i've innitialized what i need. Going on, now i need to set the variables of the struct pointer to the specific settings that i want (The struct is going to be used as a option/settings thingy). The struct pointer is private so i wrote a getter-method that returns the address of the pointer. It's written like this (in my .cpp file of the class):
Client::Settings* Client::Thread_Settings() {
return thread_settings;
}
Now, the method is a pointer that is accessible everywhere. I'm creating a object of the class and calling the address. Then im setting the vars like so (still no error to this point).
(object already defined)
client.Thread_Settings()->AcessibilityMode = 1; //Normally i have macros that are setted to these values
client.Thread_Settings()->Raw = false;
client.Thread_Settings()->Type = 33;
Lastly, the main function executes a method from the same class as the object struct pointer. These methods have if-statements that are checking the defined variables in the struct. These if lines are written like this:
if (thread_settings->Recv_BufferAccesibilityMode == 1 /*normally instead for 1 i've a macro*/ ) {
...... //rest of code
}
Now, i've got an access violation error that reads some unwritten memory (checked in an assembler) sometimes on 0x11C and sometimes at 0x12C. The error in vs19 looks loke this:
Exception thrown: read access violation.
this->thread_settings was 0x11C.
Do anyone have any thoughts? Appreciate any help :D
My class is as follows:
class stats {
public: int strength,
perception,endurance,charisma,inteligence,agility,luck,health,stamina,mana,karma;
};
As far as I know, there shouldn't be anything wrong with it, unless I need to set up a constructor and destructor.
I create my object using the following line:
stats* mainstat=new stats;
And I have the following function to "fill" objects of the said class:
void statfiller(stats* object, int table[]){
object->strength=table[0]; object->perception=table[1];
object->endurance=table[2]; object->charisma=table[3];
object->inteligence=table[4]; object->agility=table[5];
object->luck=table[6]; object->health=table[7];
object->stamina=table[8]; object->mana=table[9];
object->karma=table[10];
}
So, until then, no problem. At least, until the following:
I create a table with the data to fill, then feed it to my fill function.
int tablet[10]; tablet[0]=5; tablet[1]=5; tablet[2]=5; tablet[3]=5;
tablet[4]=5; tablet[5]=5; tablet[6]=5; tablet[7]=50; tablet[8]=50;
tablet[9]=50; tablet[10]=0;
statfiller(mainstat*,tablet);
When I do this, a compiling error comes up, stating the syntax of my function is incorrect.
Why is it so? Do I need to use pointer(*) or address(&)? Is there something I'm missing?
Odds are, the solution is very simple, but at the moment of typing this, I just don't see what's wrong with it ^^;
Solution to this problem was the following:
The function's syntax is "void statfiller(stats* object, int table[]) ", where the stats* object serves as reference, pointer to an object of stats class.
In the function's call "statfiller(mainstat*,tablet);", the mistake I made was calling a pointer of a stat object (in this case mainstat) instead of just putting in the object.
I have been struggling with this problem for a few hours now and I've searched for every term that made sense to me. I might even have already read through a relevant answer but didn't recognize it as such because I'm a little confused by pointers.
So, I have a struct that is part of an object which is part of a chain of objects that is "anchored" (if you can call it that) in another object, which is itself part of a chain which is "anchored" in an anchor object initialized in main.
struct values
{
double val, ues;
}
class small
{
public:
values vals;
}
class big
{
public:
small *small_anchor;
}
values &getPointerToStruct(big *con)
{
values *return_vals;
if(con->small_anchor->vals.val==10)
return_vals=con->small_anchor->vals;
return (&return_vals);
}
int main()
{
values *main_values=NULL;//This is supposed to be pointing to the "vals" struct contained inside the "small" object.
big *big_anchor;
big_anchor = new big;
big_anchor->small_anchor = new small;
big_anchor->small_anchor->vals.val=10;
big_anchor->small_anchor->vals.ues=5;
main_values = getPointerToStruct(&big_anchor);//now main_values should be pointing to the "vals" struct
//I want to manipulate the value INSIDE the object itself
main_values.val++;
}
I have tried every combination of &, * and no prefix I could come up with, but nothing would give the result I was hoping for. "Closest" I got was copying "vals" (from inside the object) into "main_values" so that I could manipulate the values there, which isn't of any use to me, as I want to manipulate the SOURCE of the variables.
Also please note that I left out the process of scrolling down the chains to get to the object I was trying to reach and that "return_vals" seems arbitrary, but it happens that there are two possible candidates that could be the struct my program is looking for and the "return_vals" contains the best candidate found so far and is overwritten when a better one is found, or returned when the routine ends.
You wrote
values &getPointerToStruct(big *con)
{
values *return_vals;
if(con->small_anchor->vals.val==10)
return_vals=con->small_anchor->vals;
return (&return_vals);
}
where I think you wanted
values *getPointerToStruct(big *con)
{
values *return_vals = 0;
if(con->small_anchor->vals.val==10)
return_vals=&con->small_anchor->vals;
return (return_vals);
}
But the . in main_values.val++; is wrong anyway. You need to be consistent about whether you wanted to work with a values* or a values&. You could make all this work with a values& if you like, but then main_values should be a values& and not declared until you are ready to initialize it. return_vals would not be practical as a values& because of the stated requirement that the full code gives it a tentative address that is conditionally modified later. But even with return_vals as a values* you could still return a values& if that is what you preferred.
This c++ code is working fine , however memory validator says that I am using a deleted pointer in:
grf->filePath = fname; Do you have any idea why ? Thank you.
Dirloader.h
// Other code
class CDirLoader
{
public:
struct TKnownGRF
{
std::string filePath;
DWORD encodingType;
DWORD userDataLen;
char *userData;
};
// Other Code
CDirLoader();
virtual ~CDirLoader();
Dirloader.cpp
// Other code
void CDirLoader::AddGroupFile(const std::string& _fname)
{
// Other code including std::string fname = _fname;
TKnownGRF *grf = new TKnownGRF;
grf->filePath = fname;
delete grf; // Just for testing purposes
P.S.: This is only an code extract. Of course if I define a struct TKnownGRF inside .cpp and use it as an actual object, gfr.filepath = something, instead of pointer grf->filepath=something, than it is ok, but I do need to have it inside *.h in CDirLoader class, due to many other vector allocations.
Since the function returns void
void CDirLoader::AddGroupFile(const std::string& _fname)
the question is what are you going to do with grf?
Are you going to delete it? If so, then, why do a new? you can just declare a TKnownGRF variable on the stack! In that case, _fname is not contributing to the logic of this method.
I guess that the class CDirLoader has a member variable of type TKnownGRF, say grf_, and that need to be used in the AddsGroupFile() method, e.g.:
grf_.filepath = _fname;
Does this happen to be using an older version of STL, say, VC6, and running multithreaded? Older versions of STL's string class used a reference counted copy on write implementation, which didn't really work in a multithreaded environment. See this KB article on VC 6.
Or, it's also possible that you are looking at the wrong problem. If you call std::string::c_str() and cache the result at all, the cached result would probably be invalidated when you modified the original string. There are a few cases where you can get away with that, but it's very much implementation specific.
I have a very simple class that looks as follows:
class CHeader
{
public:
CHeader();
~CHeader();
void SetCommand( const unsigned char cmd );
void SetFlag( const unsigned char flag );
public:
unsigned char iHeader[32];
};
void CHeader::SetCommand( const unsigned char cmd )
{
iHeader[0] = cmd;
}
void CHeader::SetFlag( const unsigned char flag )
{
iHeader[1] = flag;
}
Then, I have a method which takes a pointer to CHeader as input and looks
as follows:
void updateHeader(CHeader *Hdr)
{
unsigned char cmd = 'A';
unsigned char flag = 'B';
Hdr->SetCommand(cmd);
Hdr->SetFlag(flag);
...
}
Basically, this method simply sets some array values to a certain value.
Afterwards, I create then a pointer to an object of class CHeader and pass it to
the updateHeader function:
CHeader* hdr = new CHeader();
updateHeader(hdr);
In doing this, the program crashes as soon as it executes the Hdr->SetCommand(cmd)
line. Anyone sees the problem, any input would be really appreciated
When you run into a crash, act like a crime investigator: investigate the crime scene.
what is the information you get from your environment (access violation? any debug messages? what does the memory at *Hdr look like? ...)
Is the passed-in Hdr pointer valid?
Then use logical deduction, e.g.:
the dereferencing of Hdr causes an access violation
=> passed in Hdr points to invalid memory
=> either memory wasn't valid to start with (wrong pointer passed in), or memory was invalidated (object was deleted before passing in the pointer, or someone painted over the memory)
...
It's probably SEGFAULTing. Check the pointers.
After
your adding some source code
your comment that the thing runs on another machine
the fact that you use the term 'flag' and 'cmd' and some very small datatypes
making me assume the target machine is quite limited in capacity, I suggest testing the result of the new CHeader for validity: if the system runs out of resources, the resulting pointer will not refer to valid memory.
There is nothing wrong with the code you've provided.
Are you sure the pointer you've created is the same same address once you enter the 'updateHeader' function? Just to be sure, after new() note the address, fill the memory, sizeof(CHeader), with something you know is unique like 0XDEAD, then trace into the updateHeader function, making sure everything is equal.
Other than that, I wonder if it is an alignment issues. I know you're using 8 bit values, but try changing your array to unsigned ints or longs and see if you get the same issue. What architecture are you running this on?
Your code looks fine. The only potential issue I can see is that you have declared a CHeader constructor and destructor in your class, but do not show the implementation of either. I guess you have just omitted to show these, else the linker should have complained (if I duplicate this project in VC++6 it comes up with an 'unresolved external' error for the constructor. It should also have shown the same error for the destructor if you had a... delete hdr; ...statement in your code).
But it is actually not necessary to have an implementation for every method declared in a class unless the methods are actually going to get called (any unimplemented methods are simply ignored by the compiler/linker if never called). Of course, in the case of an object one of the constructor(s) has to be called when the object is instantiated - which is the reason the compiler will create a default constructor for you if you omit to add any constructors to your class. But it will be a serious error for your compiler to compile/link the above code without the implementation of your declared constructor, so I will really be surprised if this is the reason for your problem.
But the symptoms you describe definitely sounds like the 'hdr' pointer you are passing to the updateHeader function is invalid. The reason being that the 1st time you are dereferencing this pointer after the updateHeader function call is in the... Hdr->SetCommand(cmd); ...call (which you say crashes).
I can only think of 2 possible scenarios for this invalid pointer:
a.) You have some problem with your heap and the allocation of memory with the 'new' operator failed on creation of the 'hdr' object. Maybe you have insufficient heap space. On some embedded environments you may also need to provide 'custom' versions of the 'new' and 'delete' operator. The easiest way to check this (and you should always do) is to check the validity of the pointer after the allocation:
CHeader* hdr = new CHeader();
if(hdr) {
updateHeader(hdr);
}
else
//handle or throw exception...
The normal behaviour when 'new' fails should actually be to throw an exception - so the following code will cater for that as well:
try{
CHeader* hdr = new CHeader();
} catch(...) {
//handle or throw specific exception i.e. AfxThrowMemoryException() for MFC
}
if(hdr) {
updateHeader(hdr);
}
else
//handle or throw exception...
}
b.) You are using some older (possibly 16 bit and/or embedded) environment, where you may need to use a FAR pointer (which includes the SEGMENT address) for objects created on the heap.
I suspect that you will need to provide more details of your environment plus compiler to get any useful feedback on this problem.