I have a class polymer with a static int count.
When I create a new polymer to add to an array of pointers I am using the count to find the correct location in the array and then I update the count in the constructor. While compiling in Windows it worked. However, when compiling in Linux (Ubuntu) it crashes unless I remove the updating of the count out of the constructor.
WORKS in Windows and Ubuntu:
polymerPointer[polymer::count] = new polymer();
polymer::count++;
WHEN the constructor doesn't update the static variable (see below)
polymer::polymer(){
//sets up lots of variables but doesn't update the static member
};
CRASHES in Ubuntu (works in Windows):
polymerPointer[polymer::count] = new polymer();
WHEN the constructor does update the static variable (see below)
polymer::polymer(){
//sets up lots of variables and then updates the static member
count++;
};
I can rewrite the code, but I liked not having to remember to update the variable separately, which is why I put the update in the constructor. Any ideas on what is going wrong?
You're hitting undefined behavior.
The following:
polymerPointer[polymer::count] = new polymer();
polymer::count++;
is not equivalent to
polymerPointer[polymer::count] = new polymer();
where polymer() increments polymer::count.
The undefined behavior results from the fact that you're modifying a value and using that value in the same statement:
ยง1.9 p15 If a side effect on a scalar object is unsequenced relative
to either another side effect on the same scalar object or a value
computation using the value of the same scalar object, the behavior is
undefined.
What probably is occuring is that the count is incremented and then the object is placed in that new position in the array. Now code will access the empty spot left as though it held a valid pointer, or when you get to the end of an array you may try to place the pointer out of the bounds of the array.
It's bad design to put the count increment in a different place than where you actually insert into the array. What you should do is write a static member function that adds elements to the array and updates the count, and then use that instead of manually creating the object and manually placing it in the array, while expecting the count to get updated automatically.
class polymer {
static void create_new_polymer() {
polymerPointer[polymer::count] = new polymer();
count++;
}
};
Even better would be to just use a vector and have it manage it's own count:
polymerPointer.push_back(new polymer());
The compiler may legally evaluate polymerPointer[polymer::count] before new polymer(); or the other way around, as it wishes. This means that you cannot depend on polymer::count to be the original value. You must use something more deterministic, like std::vector<std::unique_ptr<Polymer>>?
It could be due to an uninitialised variable. Try stepping through the code in a debugger or just printing out the value of count.
You could also check that polymerPointer points to allocated memory (how much memory did you allocate for the storage and is it enough for all values of count?).
Your problem is that the standard doesn't guarantee in which order your statement is executed, so polymerPointer[polymer::count] = new polymer(); might evaluate polymer::count either before or after new polymer(); is executed.
If you change polymer::count inside of polymers constructor and polymer::count is evaluated after new polymer() you obviously skip indices, which is likely what leads to your crashes.
But do you really have any pressing reason to use what seems like a c-style array here instead of using std::vector (which would not need the extra count variable)? Furthermore if you have the choice you really shouldn't use manual memory management, so use std::unique_ptr or std::shared_ptr if you have access to C++11, std::tr1::shared_ptr or boost::shared_ptr otherwise. If you are using boost boost::ptr_vector is also an option
The easiest fix would be to split that assignment in two, hence introducing a sequencing:
polymer*& insert_point = polymerPointer[polymer::count];
insert_point = new polymer();
The reasoning is explained in other answers.
Related
I would appreciate some help to initialize a double pointer. here is my code:
EstablishmentCloud_site **__ptrTest;
EstablishmentCloud_site siteCloud;
__ptrTest = new EstablishmentCloud_site *[1];
siteCloud.f_site_id="site";
siteCloud.f_status="status";
siteCloud.f_name="name";
*(__ptrTest[0])=siteCloud;
It seems that initialisation of __ptrTest is wrong because I get a "Access violation reading location". What is the good syntax?
Of course, at the end, this code will be in a loop to insert several EstablishmentCloud_site in my __ptrTest.
Thanks!
The syntax to use depends on what you are trying to accomplish. As it stands, it is not clear if there is a syntax error or a logical error.
Here is what the current syntax says to do (skipping some irrelevant steps):
Create an array of pointers (these pointers are garbage initially).
Assign a value to the object pointed to by the first of these pointers (but since the pointer contains garbage, dereferencing it is an access violation).
You are missing the step where the pointer is assigned a valid value. If the intent is to point to siteCloud, Killzone Kid's answer is the way to go (ptrTest[0] = &siteCloud; I am not going to advocate using a double underscore). If the intent is to copy the values from siteCloud to the object pointed to by the array element, you need to create that object first (something like ptrTest[0] = new EstablishmentCloud_site).
The former method (assigning addresses) can run into problems if the objects do not have a sufficiently long lifespan. The latter method (more allocations) can run into memory leaks if you do not adequately clean up afterwards. If either of these are problems in your situation, you may want to reconsider if you really want an array of pointers. (You might find that there are standard templates that can make your implementation easier.)
With your help, I've managed to create this function. I hope it's not so crappy code! Thanks!
establishmentConversion(mySourceObject establishmentSource)
{
EstablishmentCloud__establishment establishmentCloud;
[...]
establishmentCloud.site_list = new EstablishmentCloudcloud_siteArray;
establishmentCloud.site_list->__ptr = new EstablishmentCloud__cloud_site *;
for(int i=0; i<(*(establishmentSource.site_list)).__size; i++)
{
establishmentCloud.site_list->__ptr[i] = new EstablishmentCloud__cloud_site;
establishmentCloud.site_list->__ptr[i]->f_site_id=(*((*(establishmentSource.site_list)).__ptr[i])).f_site_id;
establishmentCloud.site_list->__ptr[i]->f_status=(*((*(establishmentSource.site_list)).__ptr[i])).f_status;
establishmentCloud.site_list->__ptr[i]->f_name=(*((*(establishmentSource.site_list)).__ptr[i])).f_name;
}
return establishmentCloud;
}
I tried a few Google searches before making this post, but to be honest I don't know what to search for. I have a C++ project and have been happily going about using the GNU compilers (g++). Today I tried to compile with clang++ and got a segfault.
Fine, ok, I can deal with this. After perusing my code and printing some stuff I was able to fix the problem. However the solution deeply troubles and confuses me.
Here's the situation: I'm using a tree-like data structure that stores a class called Ligament, but I'm storing it in a std::vector. I do this by storing a vector of "children" which are really just integer offsets between parent and child within the vector. In this way I can access children by using the this pointer, i.e
child = this[offset];
However, none of that's important. Here's this issue: I have an Ligament::addChild(int) function that takes an integer and pushes it to the back of a vector that is a member of Ligament:
void Ligament::addChild(uint32_t offset){
children.push_back(offset);
}
Very simple stuff. In general I pass to addChild an argument that gets returned from a recursive function called fill:
//starting at root
uint32_t fill(vector<Ligament>& lVec, TiXmlElement * el){
//store current size here, as size changes during recursion
uint32_t curIdx = lVec.size();
lVec.push_back(createLigament());
//Add all of this Ligament's children
TiXmlElement * i = el->FirstChildElement("drawable");
for (; i; i=i->NextSiblingElement("drawable")){
uint32_t tmp = fill(lVec, i) - curIdx;
lVec[curIdx].addChild(tmp);
//Does not work in clang++, but does in g++
//lVec[curIdx].addChild(fill(lVec,i)-curIdx);
}
//return the ligament's index
return curIdx;
}
The fill function gets called on an XML element and goes through its children, depth first.
Sorry if all that was unclear, but the core of the problem seems to be what's in that for loop. For some reason I have to store the return value of the fill call in a variable before I send it to the addChild function.
If I don't store it in a temporary variable, it seems as though the addChild function does not change the size of children, but I can't imagine why.
To check all this I printed out the size of the children vector before and after these calls, and it never went above 1. Only when I called addChild with a value that wasn't directly returned from a function did it seems to work.
I also printed out the values of offset inside the addChild function as well as inside the for loop before it was called. In all cases the values were the same, both in clang++ and in g++.
Since the issue is resolved I was able to move forward, but this is something I'd expect to work. Is there something I'm doing wrong?
Feel free to yell at me if I could do more to make this question clearer.
ALSO: I realize now that passing lVec around by reference through these recursions may be bad, as a push_back call may cause the address to change. Is this a legitimate concern?
EDIT:
So as people have pointed out, my final concern turned out to be related to the issue. The fill call has the potential to resize the vector, while the lVec[curIdx] = modifier will change an element in the vector. The order in which these things occurs can have drastic consequences.
As a follow up, is using the tmp variable acceptable? There's still the issue of a reallocation occuring...I think I will use SHR's suggestion of a map, then convert it to a vector when all is said and done.
// Does not work in clang++, but does in g++:
lVec[curIdx].addChild(fill(lVec,i)-curIdx);
The bug you are seeing is due to dependence on order of evaluation. Since fill(lVec, i) may cause lVec to reallocate its elements, the program will have undefined behavior if lVec[curIdx] is evaluated before fill(lVec,i). The order of evaluation of function arguments - and the postfix expression that determines which function to call - is unspecified.
I think it is undefined behavior.
you push into vector, and change it in the same command.
one compiler may do the fill first and the other may get lVec[curIdx] first.
if it is the case it will work for both compilers when you use map<uint32_t,uint32_t> instead of the vector. since map doesn't require the memory to be sequential.
I am trying to understand the implications / side effects / advantages of a recent code change someone made. The change is as follows:
Original
static List<type1> Data;
Modified
static List<type1> & getData (void)
{
static List<type1> * iList = new List<type1>;
return * iList;
}
#define Data getData()
What purpose could the change serve?
The benefit to the revision that I can see is an issue of 'initialization time'.
The old code triggered an initialization before main() is called.
The new code does not trigger initialization until getData() is called for the first time; if the function is never called, you never pay to initialize a variable you didn't use. The (minor) downside is that there is an initialization check in the generated code each time the function is used, and there is a function call every time you need to access the list of data.
If you have a variable with static duration, it is created when the application is initialized. When the application terminates the object is destroyed. It is not possible to control the order in which different objects are created.
The change will make the object be created when it is first used, and (as it is allocated dynamically) it will never be destroyed.
This can be a good thing if other objects need this objects when they are destroyed.
Update
The original code accessed the object using the variable Data. The new code does not have to be modified in any way. When the code use Data it will, in fact, be using the macro Data, which will be expanded into getData(). This function will return a reference to the actual (dynamically allocated object). In practice, the new code will work as a drop-in replacement for the old code, with the only noticable difference being what I described in the original answer above.
Delaying construction until the first use of Data avoids the "static initialization order fiasco".
Making some guesses about your List,... the default-constructed Data is probably an empty list of type1 items, so it's probably not at great risk of causing the fiasco in question. But perhaps someone felt it better to be safe than sorry.
There are several reasons why that change was made :
to prevent the static order initialization fiasco
to delay the initialization of the static variable (for whatever reason)
I have a C++ class where I have a dynamically-allocated array of pointers to structs. I have a member function to "add an item" to this array by assigning an index of the array to the pointer to a dynamically allocated instance of the struct.
I have sort_arr initialized with sort_arr = new node *[this->max_items];.
In my assignment function I have sort_arr[this->num_items] = item; where the pointer is being passed as an argument with node *item.
In this function, I am able to access a member variable using (*sort_arr[i]).key_a (where i is the index), but once another item is added, this reference is no longer valid and causes a seg fault.
Is the pointer being deallocated, and if so, is it possible to prevent this?
EDIT: Sorry for the ambiguity here. I am trying to understand the problem generally and not specifically (in a pedagogical sort of way). I was hoping it was a problem with my conceptual approach. Given that it probably isn't, here are some more details:
node is defined as node **sort_arr; in the class declaration and then initialized by the constructor as sort_arr = new node *[this->max_items];. The insert method of the class executes: sort_arr[this->num_items] = item;, where item is passed with node *item.
It seems that after an item 'n2' is inserted after 'n1', 'n1' is no longer accessible via the reference (*sort_arr[num_items]).key_a. key_a is a member variable of the node struct.
EDIT 2: node *item is dynamically allocated outside of the class (in the main function).
The code you posted looks basically correct (if not the best way to do this sort of thing), but I can't tell what key_a is, or what context you are calling it in. Because of that, it's hard to tell exactly what the problem is. Posting the entire body of your function might be useful.
The only way something you allocated via new will be deallocated is if you (or some code you call) explicitly calls delete. That's pretty much the whole point of dynamic memory allocation, to allow your objects to live after the stack frame gets popped off.
My best guess with the current information is that you're trying to access a local value that got allocated on the stack after returning from the function. For example, this would cause a problem:
some_type* some_function(int i)
{
// ...
some_type p = (*sort_arr[i]).key_a; // p is a copy of key_a, allocated on the stack
// ...
some_type* result = &p;
return result;
}
In this scenario, p would be okay to return directly (if you changed the return type to some_type instead of some_type*), but you can't return a pointer to a local value. The local value is no longer valid after the function exits. This often causes a segfault.
Make sure that this->num_items as well asi is less than this->max_items and greater than -1, as this could be the cause of seg-fault.
Don't use dynamic arrays if it isn't for lecturing. Use a simple and save std::vector. It handles nearly everything that could go wrong. Try with that and see if there's still a seg-fault.
As noted, the code does appear to be correct. The problem was unrelated to the referenced code. I had been debugging some memory leaks and was deleting the referenced items, which was in turn causing the problem (quite obviously now that I see that).
I appreciate everyone's help and I'm sorry if I drove anyone crazy trying to find what was wrong.
I am extending the Visual Studio 2003 debugger using autoexp.dat and a DLL to improve the way it displays data in the watch window. The main reason I am using a DLL rather than just the basic autoexp.dat functionality is that I want to be able to display things conditionally. e.g. I want to be able to say "If the name member is not an empty string, display name, otherwise display [some other member]"
I'm quite new to OOP and haven't got any experience with the STL. So it might be that I'm missing the obvious.
I'm having trouble displaying vector members because I don't know how to get the pointer to the memory the actual values are stored in.
Am I right in thinking the values are stored in a contiguous block of memory? And is there any way to get access to the pointer to that memory?
Thanks!
[edit:] To clarify my problem (I hope):
In my DLL, which is called by the debugger, I use a function called ReadDebuggeeMemory which makes a copy of the memory used by an object. It doesn't copy the memory the object points to. So I need to know the actual address value of the internal pointer in order to be able to call ReadDebuggeeMemory on that as well. At the moment, the usual methods of getting the vector contents are returning garbage because that memory hasn't been copied yet.
[update:]
I was getting garbage, even when I was looking at the correct pointer _Myfirst because I was creating an extra copy of the vector, when I should have been using a pointer to a vector. So the question then becomes: how do you get access to the pointer to the vector's memory via a pointer to the vector? Does that make sense?
The elements in a standard vector are allocated as one contiguous memory chunk.
You can get a pointer to the memory by taking the address of the first element, which can be done is a few ways:
std::vector<int> vec;
/* populate vec, e.g.: vec.resize(100); */
int* arr = vec.data(); // Method 1, C++11 and beyond.
int* arr = &vec[0]; // Method 2, the common way pre-C++11.
int* arr = &vec.front(); // Method 3, alternative to method 2.
However unless you need to pass the underlying array around to some old interfaces, generally you can just use the operators on vector directly.
Note that you can only access up to vec.size() elements of the returned value. Accessing beyond that is undefined behavior (even if you think there is capacity reserved for it).
If you had a pointer to a vector, you can do the same thing above just by dereferencing:
std::vector<int>* vecptr;
int* arr = vecptr->data(); // Method 1, C++11 and beyond.
int* arr = &(*vecptr)[0]; // Method 2, the common way pre-C++11.
int* arr = &vec->front(); // Method 3, alternative to method 2.
Better yet though, try to get a reference to it.
About your solution
You came up with the solution:
int* vMem = vec->_Myfirst;
The only time this will work is on that specific implementation of that specific compiler version. This is not standard, so this isn't guaranteed to work between compilers, or even different versions of your compiler.
It might seem okay if you're only developing on that single platform & compiler, but it's better to do the the standard way given the choice.
Yes, The values are stored in a contiguous area of memory, and you can take the address of the first element to access it yourself.
However, be aware that operations which change the size of the vector (eg push_back) can cause the vector to be reallocated, which means the memory may move, invalidating your pointer. The same happens if you use iterators.
vector<int> v;
v.push_back(1);
int* fred = &v[0];
for (int i=0; i<100; ++i)
v.push_back(i);
assert(fred == &v[0]); // this assert test MAY fail
I couldn't implement the solutions suggested by Gman and Roddy once I changed from having a vector variable to having a pointer to a vector, quite probably because I'm just too clueless.
I have found the pointer I was looking for though: _Myfirst
So my code works when I use
std::vector<int>* vec;
int *vMem = vec->_Myfirst;
I'm surprised that I've got access to _Myfirst. I would have expected it to be a private member. But obviously not...
You couldn't implement the solutions suggested by Gman and Roddy because they answers, seemingly correct, but has nothing to do with you situation.
When developing an Addin Dll for Expression Evaluation (EE) to use with autoexp.dat, you are getting one raw pointer to the vector object from your process. But the Dll is running in the process of Visual Studio Debugger, so the only way to access the vector's data is through the ReadDebuggeeMemory function.
You should use that raw pointer and ReadDebuggeeMemory() to read the memory occupied by an object in Debugee process to the local buffer/object. (local for Debugger process, meaning your dll). Then get necessary data from local object, if it is a pointer, than you have to use ReadDebuggeeMemory() again, to read the object pointed by it to another local location. And so on.
For vector's (I haven't done it myself to be more specific), you should
1. Read (ReadDebuggeeMemory()) the vector object to the local one.
2. Get the size of the vector (I assume it is a non pointer data in vector class)
3. Get the pointer to that the contiguous memory location, and read (ReadDebuggeeMemory()) that block to the local buffer/block. Block size is sizeof(VectorType) * VectorSize in bytes. (if it is not continuous, then things will be more complicated, but the idea is the same).
4. Since your vector contains pointers, you have to read (ReadDebuggeeMemory()) every item separately into local memory.