I'm writing some code to do bitmap blending and my function has a lot of options for it. I decided to use switch to handle those options, but then I needed to either put switch inside a loop (I read that it affects performance) or to assign loop for each switch case (makes code way too big). I decided to do this using third way (see below):
/* When I need to use static value */
BYTE *pointerToValue = (BYTE*)&blendData.primaryValue;
BYTE **pointerToReference = &pointerToValue;
*pointerToReference = *pointerToReference - 3;
/* When I need srcLine's 4th value (where srcLine is a pointer to BYTE array) */
BYTE **pointerToReference = &srcLine;
while (destY2 < destY1) {
destLine = destPixelArray + (destBytesPerLine * destY2++) + (destX1 * destInc);
srcLine = srcPixelArray + (srcBytesPerLine * srcY2++) + (srcX1 * srcInc);
for (LONG x = destX1; x < destX2; x++, destLine += destInc, srcLine += srcInc) {
BYTE neededValue = *(*pointerToReference + 3); //not yet implemented
destLine[0] = srcLine[0];
destLine[1] = srcLine[1];
destLine[2] = srcLine[2];
if (diffInc == BOTH_ARE_32_BIT)
destLine[3] = srcLine[3];
}
}
Sometimes I might need to use srcLine[3] or blendData.primaryValue. srcLine[3] can be accessed easily with *(*pointerToReference + 3), however to access blendData.primaryValue I need to reduce pointer by 3 in order to keep the same expression (*(*pointerToReference + 3)).
So here are my questions:
Is it safe to set pointer out of its memory range if later it is
going to brought back?
I'm 100% sure that it won't be used when it's out of range, but can
I be sure that it won't cause any kind of access violation?
Maybe there is some kind of similar alternative to use one variable
to capture a value of srcLine[3] or blendData.primaryValue
without if(), like it's done in my code sample?
Because of #2, no usage, the answer to #1 is yes, it is perfectly safe. Because of #1, then, there is no need for #3. :-)
An access violation could only happen if the pointer were actually used.
Related
I am attempting to write multiple nodes in a single request, however I have not found any documentation or examples on how to do that, every time I find anything regarding the issue, a single node is written. Based on my understanding of the open62541 library (which is not much), I've attempted to do this like so:
void Write_from_3_to_5_piece_queue() {
char NodeID[128];
char NodeID_backup[128];
char aux[3];
bool bool_to_write = false;
strcpy(NodeID_backup, _BaseNodeID);
strcat(NodeID_backup, "POU.AT2.piece_queue["); // this is where I want to write, I need only to append the array index in which to write
UA_WriteRequest wReq;
UA_WriteValue my_nodes[3]; // this is where I start to make things up, I'm not sure this is the correct way to do it
my_nodes[0] = *UA_WriteValue_new();
my_nodes[1] = *UA_WriteValue_new();
my_nodes[2] = *UA_WriteValue_new();
strcpy(NodeID, NodeID_backup);
strcat(NodeID, "3]"); //append third index of array (will write to piece_queue[3])
my_nodes[0].nodeId = UA_NODEID_STRING_ALLOC(_nodeIndex, NodeID);
my_nodes[0].attributeId = UA_ATTRIBUTEID_VALUE;
my_nodes[0].value.hasValue = true;
my_nodes[0].value.value.type = &UA_TYPES[UA_TYPES_BOOLEAN];
my_nodes[0].value.value.storageType = UA_VARIANT_DATA_NODELETE;
my_nodes[0].value.value.data = &bool_to_write;
strcpy(NodeID, NodeID_backup);
strcat(NodeID, "4]");
my_nodes[1].nodeId = UA_NODEID_STRING_ALLOC(_nodeIndex, NodeID);
my_nodes[1].attributeId = UA_ATTRIBUTEID_VALUE;
my_nodes[1].value.hasValue = true;
my_nodes[1].value.value.type = &UA_TYPES[UA_TYPES_BOOLEAN];
my_nodes[1].value.value.storageType = UA_VARIANT_DATA_NODELETE;
my_nodes[1].value.value.data = &bool_to_write;
strcpy(NodeID, NodeID_backup);
strcat(NodeID, "5]");
my_nodes[2].nodeId = UA_NODEID_STRING_ALLOC(_nodeIndex, NodeID);
my_nodes[2].attributeId = UA_ATTRIBUTEID_VALUE;
my_nodes[2].value.hasValue = true;
my_nodes[2].value.value.type = &UA_TYPES[UA_TYPES_BOOLEAN];
my_nodes[2].value.value.storageType = UA_VARIANT_DATA_NODELETE;
my_nodes[2].value.value.data = &bool_to_write;
UA_WriteRequest_init(&wReq);
wReq.nodesToWrite = my_nodes;
wReq.nodesToWriteSize = 3;
UA_WriteResponse wResp = UA_Client_Service_write(_client, wReq);
UA_WriteResponse_clear(&wResp);
UA_WriteRequest_clear(&wReq);
return;
}
At first I didn't have much hope that this would work, but it turns out this actually writes the values that I wish. The problem is that on UA_WriteRequest_clear(&wReq); I trigger an exception in the open62541 library:
Also, I know I can write multiple values to arrays specifically, even though in this particular example that would fix my issue, that's not what I mean to do, this example is just to simplify my problem. Just suppose I have a multi-type structure and I want to write to it, all in a single request. I appreciate any help!
First of all, this is bad:
UA_WriteValue my_nodes[3];
my_nodes[0] = *UA_WriteValue_new();
my_nodes[1] = *UA_WriteValue_new();
my_nodes[2] = *UA_WriteValue_new();
my_nodes is already created on the stack, and then you are copying the content of a new object into it by dereferencing. This definitely leads to memory leaks. You probably want to use UA_WriteValue_init() instead.
Never ever dereference the return value of a new() function.
Let's go bottom up:
UA_WriteRequest_clear(&wReq) is recursively freeing all content of the wReq steucture.
This means that it will also call:
UA_Array_delete(wReq.nodesToWrite, wReq.nodesToWriteSize, ...)
which in turn calls UA_free(wReq.nodesToWrite)
And you have:
wReq.nodesToWrite = my_nodes;
with
UA_WriteValue my_nodes[3];
This means that you are assigning a variable, which lives on the stack to a pointer, and later this pointer is freed. free can only delete stuff which is on the heap and not stack, and therefore it fails.
You have two options now:
If you still want to use the stack trick the UA_clear in thinking that the variable is empty:
wReq.nodesToWrite = NULL;
wReq.nodesToWriteSize = 0;
UA_clear(&wReq);
Put the nodes on the heap:
Instead of
UA_WriteValue my_nodes[3]; use Something like UA_WriteValue *my_nodes = (UA_WriteValue*)UA_malloc(sizeof(UA_WriteValue)*3);
Also I strongly recommend that you either use valgrind or clang memory sanitizer to avoid all these memory issues.
I have been working on a program that basically used brute force to work backward to find a method using a given set of operations to reach the given number. So, for example, if I gave in a set of operations +5,-7,*10,/3, and a given number say 100(*this example probably won't come up with a solution), and also a given max amount of moves to solve (let's say 8), it will attempt to come up with a use of these operations to get to 100. This part works using a single thread which I have tested in an application.
However, I wanted it to be faster and I came to multithreading. I have worked a long time to even get the lambda function to work, and after some serious debugging have realized that the solution "combo" is technically found. However, before it is tested, it is changed. I wasn't sure how this was possible considering the fact that I had thought that each thread was given its own copy of the lambda function and its variables to use.
In summary, the program starts off by parsing the information, then passes the information which is divided by the parser as paramaters into the array of an operation object(somewhat of a functor). It then uses an algorithm which generated combinations which are then executed by the operation objects. The algorithm, in simplicity, takes in the amount of operations, assigns it to a char value(each char value corresponds to an operation), then outputs a char value. It generates all possible combinations.
That is a summary of how my program works. Everything seems to be working fine and in order other than two things. There is another error which I have not added to the title because there is a way to fix it, but I am curious about alternatives. This way is also probably not good for my computer.
So, going back to the problem with the lambda expression inputted with the thread as seen is with what I saw using breakpoints in the debugger. It appeared that both threads were not generating individual combos, but more rather properly switching between the first number, but alternating combos. So, it would go 1111, 2211, rather than generating 1111, 2111.(these are generated as the previous paragraph showed, but they are done a char at a time, combined using a stringstream), but once they got out of the loop that filled the combo up, combos would get lost. It would randomly switch between the two and never test the correct combo because combinations seemed to get scrambled randomly. This I realized must have something to do with race conditions and mutual exclusion. I had thought I had avoided it all by not changing any variables changed from outside the lambda expression, but it appears like both threads are using the same lambda expression.
I want to know why this occurs, and how to make it so that I can say create an array of these expressions and assign each thread its own, or something similar to that which avoids having to deal with mutual exclusion as a whole.
Now, the other problem happens when I at the end delete my array of operation objects. The code which assigns them and the deleting code is shown below.
operation *operations[get<0>(functions)];
for (int i = 0; i < get<0>(functions); i++)
{
//creates a new object for each operation in the array and sets it to the corresponding parameter
operations[i] = new operation(parameterStrings[i]);
}
delete[] operations;
The get<0>(functions) is where the amount of functions is stored in a tuple and is the number of objects to be stored in an array. The paramterStrings is a vector in which the strings used as parameters for the constructor of the class are stored. This code results in an "Exception trace/breakpoint trap." If I use "*operations" instead I get a segmentation fault in the file where the class is defined, the first line where it says "class operation." The alternative is just to comment out the delete part, but I am pretty sure that it would be a bad idea to do so, considering the fact that it is created using the "new" operator and might cause memory leaks.
Below is the code for the lambda expression and where the corresponding code for the creation of threads. I readded code inside the lambda expression so it could be looked into to find possible causes for race conditions.
auto threadLambda = [&](int thread, char *letters, operation **operations, int beginNumber) {
int i, entry[len];
bool successfulComboFound = false;
stringstream output;
int outputNum;
for (i = 0; i < len; i++)
{
entry[i] = 0;
}
do
{
for (i = 0; i < len; i++)
{
if (i == 0)
{
output << beginNumber;
}
char numSelect = *letters + (entry[i]);
output << numSelect;
}
outputNum = stoll(output.str());
if (outputNum == 23513511)
{
cout << "strange";
}
if (outputNum != 0)
{
tuple<int, bool> outputTuple;
int previousValue = initValue;
for (int g = 0; g <= (output.str()).length(); g++)
{
operation *copyOfOperation = (operations[((int)(output.str()[g])) - 49]);
//cout << copyOfOperation->inputtedValue;
outputTuple = (*operations)->doOperation(previousValue);
previousValue = get<0>(outputTuple);
if (get<1>(outputTuple) == false)
{
break;
}
debugCheck[thread - 1] = debugCheck[thread - 1] + 1;
if (previousValue == goalValue)
{
movesToSolve = g + 1;
winCombo = outputNum;
successfulComboFound = true;
break;
}
}
//cout << output.str() << ' ';
}
if (successfulComboFound == true)
{
break;
}
output.str("0");
for (i = 0; i < len && ++entry[i] == nbletters; i++)
entry[i] = 0;
} while (i < len);
if (successfulComboFound == true)
{
comboFoundGlobal = true;
finishedThreads.push_back(true);
}
else
{
finishedThreads.push_back(true);
}
};
Threads created here :
thread *threadArray[numberOfThreads];
for (int f = 0; f < numberOfThreads; f++)
{
threadArray[f] = new thread(threadLambda, f + 1, lettersPointer, operationsPointer, ((int)(workingBeginOperations[f])) - 48);
}
If any more of the code is needed to help solve the problem, please let me know and I will edit the post to add the code. Thanks in advance for all of your help.
Your lambda object captures its arguments by reference [&], so each copy of the lambda used by a thread references the same shared objects, and so various threads race and clobber each other.
This is assuming things like movesToSolve and winCombo come from captures (it is not clear from the code, but it seems like it). winCombo is updated when a successful result is found, but another thread might immediately overwrite it right after.
So every thread is using the same data, data races abound.
You want to ensure that your lambda works only on two three types of data:
Private data
Shared, constant data
Properly synchronized mutable shared data
Generally you want to have almost everything in category 1 and 2, with as little as possible in category 3.
Category 1 is the easiest, since you can use e.g., local variables within the lambda function, or captured-by-value variables if you ensure a different lambda instance is passed to each thread.
For category 2, you can use const to ensure the relevant data isn't modified.
Finally you may need some shared global state, e.g., to indicate that a value is found. One option would be something like a single std::atomic<Result *> where when any thread finds a result, they create a new Result object and atomically compare-and-swap it into the globally visible result pointer. Other threads check this pointer for null in their run loop to see if they should bail out early (I assume that's what you want: for all threads to finish if any thread finds a result).
A more idiomatic way would be to use std::promise.
The scenario is:
I am writing a framework for a particle simulation application.
I need to add various attributes to the particles, which I don't know yet and which are different per Particle. Since an attribute would be accessed and manipulate quite often in a time critical manner, I decided to store them in a plain c array.
I would prefer to access the different kind of attributes (like pos, vel, force, etc.) by name.
So I decided to use a std::map<const std::string,double*> to store the floating point attributes.
So to my question. I try to store particle attribute values as following
double* attr = new double[3 * 10];
std::map<std::string,double*> doubleAttributes3d;
doubleAttributes3d.insert(std::make_pair("pos", attr));
for(int64_t i = 0;i<10;++i)
{
*(doubleAttributes3d["pos"] + 3 * i) = 1.0;
*(doubleAttributes3d["pos"] + 3 * i + 1) = 2.0;
*(doubleAttributes3d["pos"] + 3 * i + 2) = 3.0;
}
double * ptr = doubleAttributes3d["pos"];
for(int64_t i = 0;i<10;++i)
{
cout << *(ptr + 3 * i) << " ";
cout << *(ptr + 3 * i + 1) << " ";
cout << *(ptr + 3 * i + 2) << endl;
}
Which causes a segfault.
In particular, everytime when I try to access elements of the array.
Is there a possibility this can ever work?
(I had never the need of using a map before, maybe I simply produce an error due to syntax mistakes...) Or in other words why can't I access the memory address which I stored into the map?
Would there be another/better(/actually working) way of storing an unknown number of arrays and give them a "name" in order to access and manipulate them later?
I know there were similar questions asked around here but none of the answers worked out for me.
First question's awnser:
I tried to run it and it run without issues, producing the expected results. I used valgrind on it and it reported no undefined behaviour. Your error must be elsewhere or it was fixed when you changed the bounds of the for cycle.
Second question's awnser:
How many variables you have there? std::map is useful only if there is a lot of variables and most of them are unset for most particles.
In most cases, it's much more comfortable and far faster to index the properties with an enum, that can be used to address a standard c array. For example:
enum pp {
POS,
VEL,
FORCE,
CHARGE,
MASS,
ELECTRON_CONFIGURATION,
ppMax
}
double* particles[1000][ppMax];
particles[0][POS] = new new double[3 * 10];
// et cetera
I benchmarked a similar issue and the difference in speed was significant, even if I had to set all unused pointers to nullptr. I don't think that the additional spacial complexity matters much in this case.
I was reading the source of a hashing competition today, and came across this:
#define BYTES_IN_BLOCK 1024
struct block{
uint8_t v[BYTES_IN_BLOCK];
block(){ memset(v, 0, BYTES_IN_BLOCK); }
uint64_t& operator[](uint8_t i){ return *(uint64_t*)(v + 8 * i); }
};
Then, a little later in the code, there's this:
state = new block[cost]; // cost is a uint32_t (like 1024)
// Probably 50 lines of code.
block prev_block;
prev_block = state[foo]; // foo is a uint32_t
What I can't figure out is what this is doing. Now, I understand C, but C++ not so much. Bear with me here for a second.
This part: return *(uint64_t*)(v+8*i) should return a uint64_t, and does so when I tested it:
state->v[8*10] = 12;
uint64_t bar = *(uint64_t*)(v+8*10);
printf("%" PRIu64 "\n", bar);
So that all makes sense.
But this:
prev_block = state[foo];
Makes no sense. Since state is block*, prev_block should now "be" state, correct? But it doesn't, because their arrays are different.
state->v[8*12] = 12;
printf("%" PRIu64 "\n", (*state)[12]);
prev_block = state[12];
printf("%" PRIu64 "\n", (*(&prev_block))[12]);
So, what exactly is going on here?
You are mixing up the two operator[]s involved here. In your last example, you set state[0][12] = 12, and you're comparing it to state[12][12]. Since state is a block*, state[n] is just normal array access; it doesn't invoke the operator[] defined in block.
state = new block[cost];
prev_block = state[foo];
is analogous to:
int* arr = new int[size];
int a = arr[index];
That's basic C++. I am not sure why that is confusing.
There is confusion with a number of concepts here. I'm going to blast through all the ones I see because they are all important, not just the immediate answer.
state is a pointer to block, but state[0] should just be a block, specifically the first block in state and also the result of *state.
prev_block = state[foo];
All of the data in block is simple, just a self-contained array of bytes, so it should be directly copy-able without any special assistance. prev_block = state[foo] should copy state[foo] to prev_block. Since it's a copy, the addressing will be different.
In the printout code provided:
state->v[8*12] = 12;
Breaking his down for clarity. state-> is going to access the first element of the state array. state->v[8*12] is going to access v[8*12] of state[0]. state->v[8*12] = 12; is going to set v[8*12] of state[0]to 12. This means byte 96 of v is going to be 12. To reference a different state you can use (state + array_index)->v[8*12]; or state[array_index].v[8*12]; I find the latter more readable.
printf("%" PRIu64 "\n", (*state)[12]);
(*state) gives you the first state in the array, AKA state[0]. (*state)[12] uses state[0]'s [] operator, defined as uint64_t& operator[](uint8_t i){ return *(uint64_t*)(v + 8 * i); }
This is going to return a 64 bit int starting at the address of state[0].v[12*8] and comprised of the next 8 bytes of array v (v[96] through v[103], resulting in 12,0,0,0,0,0,0,0). This will be 12 or a god-awful big number depending on the system's endian. The wrapping printf is going to print the returned number.
prev_block = state[12];
Is going to copy the 13th element of the state array to prev_block, assuming enough blocks were created by state = new block[cost];. Nothing magical, but there shouldn't be anything there but zeros because the only state that has any values set is state[0]. You either wanted to copy state[0] here or write to state[12] up a few lines.
printf("%" PRIu64 "\n", (*(&prev_block))[12]);
the * and & cancel each other out before accomplishing anything. It will then print out the result of using the block [] operator as above. Should be zero.
I have been writing some code to create a byte array I will be sending over a socket to another process. However noticed some really odd behavior regarding my byte[].
The cout at the end prints out 99, however looking at my code, I couldn't find where the value is being set. I create a char array of size sendingSize which is a constant. I don't set the value 307200* 3 so I don't understand how it prints out with a value...
char tosend[sendingSize];
//Send over the frame
for(int i = 0; i < 307200; i++)
{
tosend[i * 3] = (byte)imCopy[i/640][i%640].red;
tosend[i * 3+1] = (byte)imCopy[i/640][i%640].green;
tosend[i * 3+2] = (byte)imCopy[i/640][i%640].blue;
}
char *bytePointer = tosend;
cout<<(int)tosend[307200* 3]<<endl;
Your code does not write any value into index 307200*3 (because the highest index your for loop reaches is 307199). So you are reading some byte from memory beyond the declared size of your array. This is undefined behaviour and anything could happen.
Some other programming languages (such as Java) do automatic range checking on arrays and would throw an exception in this case. In C++, you are expected to do the right thing and the compiler doesn't generate range checking code for you.