I know this may sound strange, but yes, it's 2009 and I need to write small application using BCB5 :)
The problem is that DynamicArray throws OutOfBound exception when trying to expand it from within worker thread.
I have global variable, let's say
DynamicArray<double> X;
In main thread I check the length of array and I get 0, which is OK (length wasn't set)
Application->MessageBox(itoa(X.Length,str , 10), "", MB_OK);
Below is my worker thread class
class ArrayModifierThread : public TThread
{
private:
DynamicArray<double> __thread X;
protected:
void __fastcall Execute();
public:
__fastcall ArrayModifierThread(bool CreateSuspended);
void setX(DynamicArray<double> &a);
};
So far so good. Next I create new thread:
ArrayModifierThread *t = new ArrayModifierThread(true);
t->setX(X); // Pass reference to my global DynamicArray
t->Resume();
Here the Execute() method gets executed:
void __fastcall ArrayModifierThread::Execute()
{
X.Length = 10;
X[5] = 45.5;
}
What I'd expect is that global array is expanded and 6th element gets value of 45.5.
But closer investigation from within main thread gives Length = 0 and ArrayOfBounds Exception:
Application->MessageBox(itoa(__X.Length,str , 10), "", MB_OK);
Application->MessageBox(itoa(__X[5],str , 10), "", MB_OK);
Could anybody tell me what I've missed?
In your Execute method you're modifying the thread's X field, not the global X variable. Although the setX method receives its argument by reference, the member variable is not a reference. It stores a copy of the DynamicArray value, and changing the Length property ensures that it refers to a unique array.
The setX function receives a reference to the global variable, as you correctly observe in your "answer," but it doesn't keep a reference to it. It instead makes a copy of it when it assigns the object's X field.
Perhaps you intended to declare X as a reference as well:
private:
DynamicArray<double>& X;
That could work. Your setX function wouldn't work anymore since you're not allowed to "re-seat" a reference after it's been initialized. Instead, you'd need to initialize it in the thread's constructor:
ArrayModifierThread(DynamicArray<double>& a): X(a) { ... }
You could also store a pointer to the array instead of a reference:
private:
DynamicArray<double>* X;
public:
void setX(DynamicArray<double>& a) {
X = &a;
}
protected:
void Execute() {
X->Length = 10;
(*X)[5] = 45.5;
}
Something else you need to be aware of is that your code is not thread-safe. (Neither is mine here.) You have multiple threads modifying the same shared resource (the array) without any protection, such as a critical section. That's beyond the scope of this question, though. Search Stack Overflow and the rest of the Web first, and then come back to ask a new question if you need help with that issue.
It will not work as the member X is not a reference. When you call set() you are making a local copy of the object, then Execute() is modifying the local version.
class ArrayModifierThread : public TThread
{
private:
DynamicArray<double> __thread X;
void __fastcall ArrayModifierThread::Execute()
{
X.Length = 10;
X[5] = 45.5;
}
There are three alternative solutions:
Make the your local member variable X a reference.
Since the reference must be initialized on construction you can not use set() to modify it, so pass the reference to the constructor of your object and save it there.
Make the your local member variable X a pointer.
When using set() take the address of the passed in parameter (note it is a reference so you will get the address of the object it is referencing). This also means that the execute needs to be modified to take into account that X is a pointer.
Do not use a local member variable. Just modify the global directly.
Well, it's not quite clear to me.
I thought because of void setX(DynamicArray &a) the worker thread gets a reference to a global variable.
Could you post sample code how should it be done?
This is how my void setX(DynamicArray &a) looks like:
void ArrayModifierThread::setX(DynamicArray<double> &a)
{
X = a;
}
Related
Is the following code (func1()) correct if it has to return i? I remember reading somewhere that there is a problem when returning a reference to a local variable. How is it different from func2()?
int& func1()
{
int i;
i = 1;
return i;
}
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
This code snippet:
int& func1()
{
int i;
i = 1;
return i;
}
will not work because you're returning an alias (a reference) to an object with a lifetime limited to the scope of the function call. That means once func1() returns, int i dies, making the reference returned from the function worthless because it now refers to an object that doesn't exist.
int main()
{
int& p = func1();
/* p is garbage */
}
The second version does work because the variable is allocated on the free store, which is not bound to the lifetime of the function call. However, you are responsible for deleteing the allocated int.
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int* p = func2();
/* pointee still exists */
delete p; // get rid of it
}
Typically you would wrap the pointer in some RAII class and/or a factory function so you don't have to delete it yourself.
In either case, you can just return the value itself (although I realize the example you provided was probably contrived):
int func3()
{
return 1;
}
int main()
{
int v = func3();
// do whatever you want with the returned value
}
Note that it's perfectly fine to return big objects the same way func3() returns primitive values because just about every compiler nowadays implements some form of return value optimization:
class big_object
{
public:
big_object(/* constructor arguments */);
~big_object();
big_object(const big_object& rhs);
big_object& operator=(const big_object& rhs);
/* public methods */
private:
/* data members */
};
big_object func4()
{
return big_object(/* constructor arguments */);
}
int main()
{
// no copy is actually made, if your compiler supports RVO
big_object o = func4();
}
Interestingly, binding a temporary to a const reference is perfectly legal C++.
int main()
{
// This works! The returned temporary will last as long as the reference exists
const big_object& o = func4();
// This does *not* work! It's not legal C++ because reference is not const.
// big_object& o = func4();
}
A local variable is memory on the stack, and that memory is not automatically invalidated when you go out of scope. From a function deeper nested (higher on the stack in memory), it’s perfectly safe to access this memory.
Once the function returns and ends though, things get dangerous.
Usually the memory is not deleted or overwritten when you return, meaning the memory at that address is still containing your data - the pointer seems valid.
Until another function builds up the stack and overwrites it.
This is why this can work for a while - and then suddenly cease to function after one particularly deeply nested set of functions, or a function with really huge sized or many local objects, reaches that stack-memory again.
It even can happen that you reach the same program part again, and overwrite your old local function variable with the new function variable. All this is very dangerous and should be heavily discouraged.
Do not use pointers to local objects!
A good thing to remember are these simple rules, and they apply to both parameters and return types...
Value - makes a copy of the item in question.
Pointer - refers to the address of the item in question.
Reference - is literally the item in question.
There is a time and place for each, so make sure you get to know them. Local variables, as you've shown here, are just that, limited to the time they are locally alive in the function scope. In your example having a return type of int* and returning &i would have been equally incorrect. You would be better off in that case doing this...
void func1(int& oValue)
{
oValue = 1;
}
Doing so would directly change the value of your passed in parameter. Whereas this code...
void func1(int oValue)
{
oValue = 1;
}
would not. It would just change the value of oValue local to the function call. The reason for this is because you'd actually be changing just a "local" copy of oValue, and not oValue itself.
We received code from a subcontractor that does essentially the following:
class Callable
{
public:
void operator()(int x)
{
printf("x = %d\n", x);
}
};
template<typename T>
class UsesTheCallable
{
public:
UsesTheCallable(T callable) :
m_callable(NULL)
{
m_callable = &callable;
}
~UsesTheCallable() {}
void call() { (*m_callable)(5); }
private:
T* m_callable;
};
This strikes me as being undefined code...they pass in the T by value to the UsesTheCallable constructor then assign the m_callable member to the address of the argument, which should go out of scope at tne end of the constructor, and so anytime I call UsesTheCallable::call(), I'm acting on an object that no longer exists.
So I tried it with this main method:
int main(int, char**)
{
UsesTheCallable<Callable>* u = NULL;
{
Callable c;
u = new UsesTheCallable<Callable>(c);
}
u->call();
delete u;
return 0;
}
I make sure that the Callable object goes out of scope before I call UsesTheCallable::call(), so I should be calling the function on memory that I don't actually own at that point. But the code works, and Valgrind reports no memory errors, even if I put some member data into the Callable class and make the operator() function act on that member data.
Am I correct that this code is undefined behavior? Is there any difference in the "defined-ness" of this code based on whether or not Callable has member data (e.g. a private int variable or something)?
Yes this is undefined behavior. After the closing brace of the constructor callable is destroyed and you have a dangling pointer.
The reason you are not seeing adverse effects is that you really aren't using the instance after it goes out of scope. The function call operator is stateless so it is not trying to access the memory that it no longer owns.
If we add some state to the callable like
class Callable
{
int foo;
public:
Callable (int foo = 20) : foo(foo) {}
void operator()(int x)
{
printf("x = %d\n", x*foo);
}
};
and then we use
int main()
{
UsesTheCallable<Callable>* u = NULL;
{
Callable c(50);
u = new UsesTheCallable<Callable>(c);
}
u->call();
delete u;
return 0;
}
Then you could see this bad behavior. In that run it outputs x = 772773112 which is not correct.
m_callable = &callable;
Am I correct that this code is undefined behavior?
Yes, this is bullsh!t, for the reason you give.
But the code works
Yeah, well, that's what happens with UB…
and Valgrind reports no memory errors
…particularly when the memory you're operating on still "belongs" to your process. There's nothing for Valgrind to detect here; it doesn't validate C++ scopes, only "physical"† memory accesses. And the program doesn't crash because nothing's yet had much of a chance to mangle the memory that used to be taken up by c.
† "Physical" in the sense that I'm referring to the OS and its memory management, rather than C++'s abstract concepts. It could actually be virtual memory or whatever.
Say I have a C++ function:
void foo(int x) {
static int bar = x;
}
If I call foo(3) then afterwards call foo(4), it is my understanding that the value of bar will still be 3. Why is this? I understand why the memory allocation part of the initialization is redundant. but why is the assignment also ignored?
It is not an "assignment". It is an initialization. And, per rules of C++ language, initialization of static objects is performed only once - when the control passes over the declaration for the very first time.
In your example, the control passes over the declaration of bar when x is 3. So, bar is initialized with 3. It will never be "reinitialized", i.e. calling foo(4) will not affect bar at all. If you want to change the value of bar after that, you have to modify bar directly.
Short answer: because the standard says so.
Long answer: that's not an assignment, but an initialisation, and it's ignored because the standard says so.
Consider some different static variables:
void foo(int x) {
static int bar = x;
static std::string s1 = "baz";
static std::string s2("baz");
static int i{2}; // C++11-style uniform initialization
}
Do you also think s1 should get "assigned" the value "baz" every time the function is called? What about s2? What about i?
None of those statements perform any assignment, they are all initializations, and they are only done once. Just because a statement includes the = character doesn't make it an assignment.
A reason why the language is defined to work that way is that it's common to use a local static variable to run a function once:
bool doInit()
{
// run some one-time-only initialization code
// ...
return true;
}
void func() {
static bool init = doInit();
// ...
}
If init got assigned a value again every time the function is called then doInit() would get called multiple times, and would fail its purpose of running one-time-only setup.
If you want to change the value every time it's called, that's easy ... just change it. But if you don't want it to keep changing then there would be no way to do that if the language worked the way you are asking about.
It would also be impossible to have static const local variable:
void func() {
static const bool init = doInit();
// ...
}
Oops, this would try to change the value of init every time it's called.
The memory location for bar is not valid until the first call to foo, which is when bar gets instantiated. bar gets initialized to x when it gets instantiated. Every call to foo afterward, bar is already instantiated and therefore already initialized.
this is initialization of static variable instead of assigning values to it. with that being said, the value of bar would always be 3 if u call foo(3) at the very first place.
Consider the following code:
int * p;
void Set()
{
int i = 7;
p = & i; // potentially disastrous
}
I know that pointing to a value that may be overwritten is bad but I recall reading that there was a way to prevent a value such as i from being lost when declared and then pointed to in this way. I've scoured my text book but have had trouble finding the exact text elaborating on this and am starting to think I may have even imagined it. Is there a way of safely pointing to a temporary value declared inside of a function? A way of making the temporary value i no longer temporary?
Thanks for all your help in advance!
I recall reading that there was a way to prevent a value such as i from being lost when declared and then pointed to in this way
The closest thing to what you mention (if I understood your sentence correctly) is the rule which allows prolonging the lifetime of a temporary when bound to a reference (§ 12.2/5 of the C++11 Standard):
struct X { int x = 0; };
X foo() { return X(); }
int main()
{
X const& x = foo(); // The lifetime of the object bound to x is prolonged
x.x = 42; // This is OK
}
However, there is no such rule for pointers nor for objects that are not temporaries.
A way of making the temporary value i no longer temporary?
In your example, i is not a temporary: it is an object with automatic storage duration. A temporary is an object whose life-time (usually) terminates at the end of the full expression that creates it (with the exception mentioned above and a few more listed in § 12.2/4-5).
taking const ref to an temporary extends liifetime of this temporary up to the end of scope of this const reference, however in your example you are not taking address of temporary but local automatic object i.
so to extends lifetime of temporary do simply:
const int& iref=int(3);
int a= iref;
//..do stuff with iref, i.e:
printf("iref: %d\n", a);
output:
iref: 3
RUN SUCCESSFUL (total time: 46ms)
The value of i has to reside in memory somewhere. If you declare it inside a function, it is likely to be allocated on the stack and will be lost when the function returns. If you really need the value to always be constant like in your example, then what you need is to declare it outside the function as static const:
int * p;
static const int i = 7;
void Set()
{
p = & i;
}
If this is not what you need, maybe you can elaborate a bit on your very minimal example code so that we can better understand what you are trying to achieve.
you can use the static keyword.
#include <stdio.h>
int *p;
void set() {
static int x = 7;
p = &x;
}
int main(){
set();
printf("%d", *p);
}
correctly prints 7.
however, I would strongly discourage using such a piece of code in anything but a research on the static keyword and pointers.
I have a class and want to create a const int variable but the value for the variable is not available to me in constructor of the class.
In initialization method of the class i get the value. Can I assign it in that method?
As I am assigning it only once (as const says) why it isn't working?
Code is as Following [Just a ProtoType] :
File : A.h
Class A
{
private :
const long int iConstValue;
public :
A();
initClassA();
}
File : A.cpp
A::A()
{
//CanNot initialize iConstValue (Don't have it)
}
A::initClassA(some params)
{
// calculation according to params for iConstValue
iConstValue = (some value)
}
This is not working. Somebody has any Solutions?
NOTE : I Can not get value for iconstValue in constructor by any way as there are some restriction. So Please don't suggest to do that.
A small example:
class A
{
public:
A():a(initial_value_of_a()) {}
private:
const int a;
int initial_value_of_a() { return 5; /* some computation here */ };
};
const doesn't mean you can only assign it once, you can never assign to a const object. A const variable is initialized once and its value cannot change. So you initialize it in the constructor, when all members and bases are initialized, then you can't change it after that.
If you can't get the value on construction you could either make the variable non-const, so you modify it, or maybe you could delay construction until you have all the data, using a placeholder until you construct the real object.
Two-stage construction is a code smell, it's certainly incompatible with const members.
You cannot do that, because you cannot change the value of a const variable. by the time initClassA runs the const data member has already been initialized (to some garbage value in this case). So you can only really initialize the data member to some value in the constructor initializer list.
If you want to set the variable only once, then you can make is non-const, and add a guard so it can only be set once. This isn't pretty but it would work:
class A
{
private :
long int iValue;
bool isInitialised;
public :
A() : iValue(0), isInitialized(false);
bool initClassA() {
if (isInitialized) return false;
iValue = something:
isInitialized = true;
return true;
}
}
But it isn't good practice to have objects that can be initialized or not. Objects should be in a coherent state when constructed, and clients should not have to check whether these objects are initialized.
Maybe what you can do, is change for a int pointer, receive this pointer in your constructor, and change the pointer where you want :P
But it will not be the same functionnality cause it will be the pointer which is const and not anymore the value :/
I think I need to change the design and I should calculate the (or get) the const variables value at constructor any how. As there is no way I can set it's value later.