Convert i of For Loop to QString - c++

Edited-
Here's where I'm getting thrown down:
for(int i=0, a=bugModel->rowCount(); i<a; i++){
qDebug() << i;
QString *BugName = new QString(QString::number(i));
setting.beginGroup(BugName->toAscii());
bugModel->setData(bugModel->index(i,0), setting.value("theBugName", "A Bug!").toString());
setting.endGroup();
delete BugName;
}
I'm trying to load a Name from the setting group and set it to a list model, for which the name will equal to i. But everytime I load the model, the information of the group '0' only shows up, because i is 0 in here. For example:
I have two setting group named '0' and '1'. I want the for loop to run 2 times so that it loads the value from these groups and set it in the QListView. But I tested it out and everytime it loads only the value of the '0' group, and when I change it to for(int i=1..) it loads the value of the group '1'.

To fix the first case, you can (*BugName) = QString::number(i) or BugName->setNum(i);, but the bigger question is what are you trying to achieve and how do you check if it stays zero? What do you expect to change? Maybe give more context?

Based on the weird use of 'a', I'm guessing that there's a bunch of other code that you didn't post. As it stands now, the loop is equivalent to for (int i = 0; i < 2; ++i), and thus only iterates through i=0 and i=1. On the first pass, it creates a new QString, assigns the address to the bugname pointer, then attempts (incorrectly) to assign a string to it. You can change the second line to *BugName = QString::number(i); and it should work. Even better, you can use one of the QString constructors and change the first line to QString* BugName = new QString(QString::number(i)) and eliminate the second line altogether.
Now for the second problem, your memory leak. After the first pass, the loop resets and you create a second qstring, overwritting bugname with the new address. Unfortunately, this orphans the first qstring you made causing a leak. Add the line delete BugName; just before the end of the loop to fix. If you're actually trying to create an array of 'BugNames' for use after the loop, you probably want to use an array instead: Put QString BugNames[2] before the loop, then use the loop to iterate through and initialize them individually via BugNames[i] = QString::number[i]. Since arrays are automatic variables, you won't need the delete part for this latter case.
Edit
Looking at your revised code, I would do it this way (old way still valid though):
for(int i=0; i < bugModel->rowCount(); i++){
qDebug() << i;
QString BugName = QString::number(i);
setting.beginGroup(BugName.toAscii());
bugModel->setData(bugModel->index(i,0), setting.value("theBugName", "A Bug!").toString());
setting.endGroup();
}
Note that your use of 'a' is redundant, since it (and indeed the loop itself) would likely be removed by the compiler. Now that I see what you're doing, I'd ditch the pointer-strings altogether and just go with a single automatic variable. As for the problem of it not working, qDebug should be outputting "0 1", yes? You can try qDebug() << BugName; after the ::number assignment, but I suspect that will output "0 1" as well. That would mean that your real issue lies somewhere in the begin/endGroup() functions, and not in this loop. If the argument to beginGroup gets assigned to something static, you might be overwritting a value with the second pass.

Related

When creating threads using lambda expressions, how to give each thread its own copy of the lambda expression?

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.

C++: Iterate using enum type

I have these codes:
for (i = 0; i <= WND_WRL; i++) {
syslog(LOG_ERR, "TESTE i=%d WND_WRL=%d", i,WND_WRL);
}
for (i = 0; i <= WND_WRL; i++) {
syslog(LOG_ERR, "OnScrDsp for i=%d WND_WRL=%d", i,WND_WRL);
m_pWnd[i] = gtk_window_new(GTK_WINDOW_POPUP);
assert(m_pWnd[i]);
}
The first for is only to explain my problem. The second is really my problem.
The source of second code can be found here:
https://github.com/HuayraLinux/intel-classmate-function-keys/blob/master/OnScrDsp.cpp
The problem:
WND_WRL variable came from
typedef enum {
WND_BRG,
WND_DSP,
WND_WRL,
} WND_ID;
struct.
In first code I can see i iterate until 2 (0,1,2) and WND_WRL will be always 2. The problem is in second code: even WND_WRL ever print 2 value, that for will iterate i until receive SIGV signal (11) and break my application (here it stop with i=384). I can understand why 384, I am not concerned about that.
What I do not understand is why the same condition provide different ways. If I change WND_WRL to number 2, I get correct code and correct app execution.
My first idea is the block of the second for maybe change WND_WRL value, but isn't happened.
I can understand if may be this code is writing in wrong memory position, but I always see WND_WRL with 2 value.
SOLUTION :
Change expression "i <=WND_WRL" to "i < WND_WRL" because m_pWnd size. It explain SIGV, but not explain why for continue until receive SIGV even if 2<=2 condition matches. Overriding memory we know can destroy a lot of things, but constants and code are read-only stack memory region, so access m_pWnd[3] and others i++ not explain why for does not stop.
Variable m_pWnd is defined in your source code as an array of pointers, with a size of 2, so valid index is 0 or 1.
GtkWidget *m_pWnd[WND_WRL];
But your loop goes i <= WND_WRL, so i=2 case will crash
m_pWnd[i] = gtk_window_new(GTK_WINDOW_POPUP);

Different output rather than expected one

Hello I am a high school student. Recently I started to do some programming in c++. But I'm stuck with the example below. I would appreciate it if you people could help me.
#include<iostream>
using namespace std;
int main()
{
int j;
for(int i=0;i<10;i++)
{
i=j;
}
cout<<j;
}
Why is the output: 2686864?
Instead I think it should be 0123456789, as the loop starts from 0. Thank you for any suggestions. .
what you want to do is pobably this:
int main()
{
int j;
for(int i=0;i<10;i++)
{
j=i;
cout<<j;
}
}
of course, you don't need the variable j here at all; you can simply output i
You haven't assigned a value to j in your declaration. In your loop the assignment is always to i, because of the order of the equals sign, and in fact you're always assigning to i the uninitialized value of j from outside your loop. So j remains at the seemingly crazy value it was initially set to be.
You want to assign the value of i to j inside the loop, i.e. reverse the equality, if you want to see it change. Also if you want to see more than one output, you need to move your print statement inside the for loop.
What you're seeing as output is not the output of multiple print statements - it's the single number automatically assigned to the initial value of j, because you didn't give it a value when you declared it. Best wishes.
First, variable "j" is not initialized. Then you are setting your loop variable to the value of j.
It looks like you're trying to build a string "0123456789", in which case, you need make j a string, and concatenate the character for each number to the end of the string in your loop.
In the loop you are looping while i < 10 and i starts at 0. If you want to set j = i then you need to switch the order of the variables because if not it could mess up the loop, but not necessarily in this situation.
Also you should initialize j to some value because if not you will get garbage values.
Also it won't output it the way you are wanting it. You should move the cout statement inside the for loop to get the out put you desire.

Debug Assertion Failed! String manipulation using pointer arithmetic

EDIT: Pastebin links to the entirety of the code at the bottom
for my CS215 course, I was given a class called String215 which is a basic string class to help in the understanding of dynamic memory allocation and pointer arithmetic with char arrays.
The class was given to me in a very basic skeleton form with prototypes but no implementations, along with a test function to test my implementations. I CAN NOT use any C String functions in this assignment.
The part of the program which is troubling is the append function, which just appends a parameter string215 object to the end of the current string215 object.
// Add a suffix to the end of this string. Allocates and frees memory.
void string215::append(const string215 &suffix)
{
char *output = new char[str_len(data)+suffix.length()+1];
for(int x = 0; x < str_len(data); x++) {
*output = *data;
output++;
data++;
}
for(int x = 0; x < suffix.length(); x++) {
*output = suffix.getchar(x);
output++;
}
*output = '\0';
output -= (str_len(data)+suffix.length()+1);
delete[] data;
data = output;
}
This portion of the code is tested in the 13th test of the test function as shown here:
string215 str("testing");
...
// Test 13: test that append works in a simple case.
curr_test++;
string215 suffix("123");
str.append(suffix);
if (strcmp(str.c_str(), "testing123") != 0) {
cerr << "Test " << curr_test << " failed." << endl;
failed++;
}
Here is the description of the append class:
Add the suffix to the end of this string. Allocates a new, larger, array; copies the old contents, followed by the suffix, to the new array; then frees the old array and updates the pointer to the new one.
My program aborts at the very end of the append function execution with the error message:
Debug Assertion Failed!
Program: [Source path]\dbgdel.cpp
Line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
...
Abort || Retry || Ignore
I'm fairly certain it has something to do with my very poor memory management. I know it's not a lot to go on, but I've been struggling with this for hours on end and can't seem to figure it out.
Here's a pastebin of the .cpp and .h file for this program
string215.cpp: http://pastebin.com/Xh2SvDKJ
string215.h: http://pastebin.com/JfAJDEVN
Any help at all is greatly appreciated!
Thanks,
RAW-BERRY
You are changing data pointer before delete[]. You need to delete[] exactly the same value you got from new[].
Also, you are incrementing output pointer str_len(data)+suffix.length() times, and you take it back by str_len(data) + suffix.length() + 1.
I would use separate variables for iteration to solve these problems.
You increment output exactly str_len(data) + suffix.length() times. Note that you don't increment output after *output = '\0';.
So to go back to the start, you should use:
output -= (str_len(data) + suffix.length());
By the way, some of the code is not very efficient. For example, getchar uses a loop instead of simply returning data[index]. You use getchar in append, which means that the performance isn't great.
EDIT: As zch says, you use delete[] data after modifying data, but note that even before that you use str_len(data) after modifying data (when deciding how many bytes to go skip back), so the calculation is wrong (and my suggestion above is also wrong, because str_len(data) is now zero).
So I think your problem is with the line
for(int x = 0; x < str_len(data); x++) {
Notice that the size of 'data' is changing at each iteration of the loop. As you increment 'x', you are decreasing the length of 'data'. Suppose 'data' is a string holding "hello": in the first iteration of the loop x=0 and str_len(data)=5; in the second iteration x=1 and str_len(data)=4. Thus the for loop executes half as many times as you need it to and 'data' does not end up pointing to the end of the data string

Array over written with last value assigned?

I have a pointer to pointer array. I am assigning each row in the while loop below and the printf inside the while loop shows each is assigned my id number 1-20.
After, out side of the while loop I iterate through the array and every element is written with id 20?
Any help is greatly appreciated. (FYI- I am using the Template2doc library and example1.c, at the bottom here- http://www.algonet.se/~thunberg/template2doc/c_version/docs/index.htm)
Below code only shows problem area, I took out the rest.
char **tableData[500]={NULL};
char *myData[500][2];
while(rc == SQLITE_ROW){
tableData[r] = myData[r];
printf(*tableData[r]); <-- Displays id 1-20 fine
r=r+1;
}//end while
tableData[r+1] = NULL;//null terminated array
for (a=0; a<r; a++){
printf("\n");
printf(*tableData[a]); <--Displays 20 elements all of id 20?
}
outputFile=insertTableData(outputFile, dataMarker, fieldMarker, tableData);
You should create something that actually compiles and reproduces the problem. Not only will it help people help you, but in doing so you may very well find the problem yourself.
In your code excerpts we have no idea:
What rc is, how its value is set, or how its value is ever going to change and therefore terminate the loop
What the initial value of r is
What the actual contents of myData are
I created this code based on what you posted, which produces the same output from both loops. So either I've missed something in what you did post, or you left something important out.
int main( int argc, char** argv ) {
#define STRING char *
STRING dummy = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ!##$%^&*()";
STRING *tableData[500]={0};
STRING myData[500][2];
int r=0;
while(r < 20){
myData[r][0] = dummy+2*r;
myData[r][1] = dummy+r;
tableData[r] = myData[r];
printf(*tableData[r]);
printf("\n");
r=r+1;
}//end while
int a;
for (a=0; a<r; a++){
printf(*tableData[a]);
printf("\n");
}
}
As pointed out, you are assigning Null at r+2 position. And are you in any way modifying tableData or myData in between the while and for loop?
How are you populating myData? I don't see a clear bug in the code example given, but I suspect the problem is that you are assigning a pointer to a buffer in myData without actually copying the contents, so that myData[0 .. r] all point to the same buffer, which will only store the most recent value read. Try this:
while(rc == SQLITE_ROW){
tableData[r] = myData[r];
if (r > 0)
printf(*tableData[r-1]);
r=r+1;
}//end while
That should print the ids from 1 to 19 fine. If it starts at id 2 instead of id 1, that suggests myData is not keeping a copy of the data, it's all pointing at the same location.
Well from what I can see right now, you're terminating your tableData at essentially r+2 from your last "duple" of information. Also, it might be a little clearer (maybe just for me) if you did tableData[0][1] or tableData[0][2] when printf'ing. That kind of makes it more clear that tableData is an index to a "structure" of 2, each containing a NULL terminated string. That might help with your debugging as well...
Try this for debugging then :
printf("Character at 0x%x : %d", tableData[a], *tableData[a]);
May be the bug is in what you took out ?
Yes, there were all pointing to the last value whe done. I went ahead and allocated memory space for each item, pointing to each accordingly.