Setting a text = a string crashes my program - nsstring

I am new at this so be gentle.
I have this function:
- (void) Morepoint {
gscore ++;
scoreString = [NSString stringWithFormat:#"%i", gscore];
lblscore.text = scoreString;
}
Where gscore is a global. scoreString is a NSString and lblscore is a label.
Every time I insert the function in my gameloop, the program stops to run.
Can anyone figure that out?
If I call the function from outside my gameloop, everything works fine, why?

You own the object returned from initWithFormat which you are responsible for releasing, but you don't own the object returned from stringWithFormat which returns an autoreleased string and so do not need to release it (if you do want to have ownership of it, you must retain it).
So for resolving your issue try to assign your value like this,
- (void) Morepoint
{
gscore ++;
scoreString = [[NSString alloc] initWithFormat:#"%i",gscore];
lblscore.text = scoreString;
}
Hope this helps you. Just Give it a try :)

Related

Swap two adjacent nodes in a doubly linked list

I am learning the concept of pointer in C programming. I wrote a function as below to swap two adjacent nodes in a doubly-linked list;
void swapNode(DLListNode *a, DLListNode *b)
{
DLListNode *temp = a;
a->value = b->value;
b->value = temp->value;
}
and it doesn't work, as the value of b passes onto a successfully but, the value of a does not pass onto b. Then I found if I wrote the code like this, it works. Could someone please kindly explain the difference to me? Much appreciated.
void swapNode(DLListNode *a, DLListNode *b)
{
DLListNode temp = *a;
a->value = b->value;
b->value = temp.value;
}
The first version does not take a copy of the value that a points to. It merely creates a second reference to what a already references. When a->value gets a new value, then of course this is synonym to temp->value getting a new value.
In the second version, you create a node, which gets its properties from what a references. So here you do make a copy of a value property (and the next and prev properties). Now, when a->value gets changed, temp is unrelated to that change, and so temp.value is still what it was before that assignment to a->value. And that is exactly what you need to happen to make a successful swap.
It would even be possible to only copy the value property value, and not the node (which also has other properties like prev and next), since you really only need to have a copy of value; nothing else (I will assume here that value is an int):
void swapNode(DLListNode *a, DLListNode *b)
{
int value = a->value;
a->value = b->value;
b->value = value;
}

Qt QMap<int, MyClass> ignores insert command

I've a question that couldn't find anywhere. I have a QMap that's ignoring the QMap.insert(Key, Value) command. Here's the code:
//gets the selected problem index on the ProblemList
int selProblem = ui->tree_projects->currentItem()->data(0, Qt::UserRole).toInt();
//creates a new problem, sets its values and then replaces the old one on the ProblemsList variable
ProblemSets nProblem;
if(!problemsList.isEmpty()) //problemsList is an attribute of MainWindow
nProblem = problemsList.value(selProblem);
// some data collection that has been omitted because isn't important
// temporary maps that will carry the modifications
QMap<int, QString> nResName, nResType;
//data insertion into the maps
//these are fine
nResName.insert(fIdx, results_model->data(results_model->index(fIdx, 0)).toString());
nResType.insert(fIdx, results_model->data(results_model->index(fIdx, 1)).toString());
//replaces the old maps with the new ones
nProblem.SetProbResultsNames(nResName);
nProblem.SetProbResultsTypes(nResType);
//replaces the old problem with the new one
problemsList.insert(selProblem, nProblem); //this is the line that's doing nothing
}
That last line appears to be doing nothing! I've even tried to use
problemsList.remove(selProblem);
problemList.insert(selProblem, nProblem);
but got a similar result: the map not being inserted at the index selProblem. It got inserted, but with an outdated value - the same one of the deleted index -. I've checked on Debug and all the indexes and variables are correct, but when the .insert hits, nothing happens.
The most awkward thing is that this code is a copy/paste that I made from another method that I'm using that does similar thing, just changing the variable names, but that one works.
EDIT 1: This is the contents of nProblem, selProb and problemsList.value(selProblem)
Just before the Line:
problemsList.insert(selProblem, nProblem);
selProb: 0
nProblem:
ProbResultsNames: "NewRow0"
ProbResultsType: "Real"
problemsList.value(selProblem):
ProbResultsNames: non-existent
ProbResultsType: non-existent
After the line
problemsList.insert(selProblem, nProblem);
selProb: 0
nProblem:
ProbResultsNames: "NewRow0"
ProbResultsType: "Real"
problemsList.value(selProblem):
ProbResultsNames: non-existent
ProbResultsType: non-existent
EDIT 2:
class ProblemSets
{
public:
ProblemSets();
virtual ~ProblemSets();
ProblemSets(const ProblemSets& other);
ProblemSets& operator=(const ProblemSets& other);
//I hid getters and setters to avoid pollution on the post
private:
int index;
bool usingBenchmark;
QString functionSelected;
QString info;
QMap<int, QString> probVars_name, probVars_type, probResultsNames, probResultsTypes;
QMap<int, float> probVars_min, probVars_max;
QMap<int, int> probVars_stpSize, probVars_stp;
int varsNumber; // holds how many vars has been created, just for display purposes
int resNumber; // holds how many results has been created, just for display purposes
};
A simple test proves that QMap works as expected:
QMap<int, QString> mm;
mm.insert(1, "Test1");
qDebug() << mm[1]; // "Test1"
mm.remove(1);
qDebug() << mm[1]; // "" (default constructed value)
mm.insert(1, "Test2");
qDebug() << mm[1]; // "Test2"
Which means that the problem lies in your code.
This statement itself is highly suspicious:
That last line appears to be doing nothing!
Because then you go on to say that the map still contains the "old value". But you removed that key, so if the insert() method didn't work, you shouldn't be getting the old value, but a default constructed value.
Which means that the problem is most likely that nProblem has the same value as the one that is previously associated to that key in the map. The map works, you values are likely wrong.
Found the issue! I didn't have both the variables declared on the copy method of the ProblemSets class.
Solved simply adding them to the copy method
MainWindow::ProblemSets::ProblemSets(const ProblemSets& other)
{
// copy
index = other.index;
usingBenchmark = other.usingBenchmark;
functionSelected = other.functionSelected;
info = other.info;
probVars_name = other.probVars_name;
probVars_type = other.probVars_type;
probVars_min = other.probVars_min;
probVars_max = other.probVars_max;
probVars_stpSize = other.probVars_stpSize;
probVars_stp = other.probVars_stp;
//here
probResultsNames = other.probResultsNames;
probResultsTypes = other.probResultsTypes;
//
varsNumber = other.varsNumber;
resNumber = other.resNumber;
}
I had this issue before with the std::vector class, and that's why I suspected that could be that. Thanks to everyone that helped!

Don't laugh, but what on earth am i missing?

OK, I probably have no business trying to learn an OOP and I'm having trouble with the simplest little first program. I am getting a message that my implementation is incomplete (I commented the line that is giving 4 errors below). What is wrong? It wants a type specifier among other things, but don't I give it one with NSString? I do notice that NSString doesn't change color to a green type color in XCODE in the implementation like it does in the interface.
ALSO, why do we need to declare the method in the interface and type the exact same thing in the implementation? that is, why the need to type the startDrinking: (NSString*) newBeverage in both?
#import <Foundation/Foundation.h>
#interface Drinks : NSObject {
NSString *beverage;
}
- (void) startDrinking: (NSString*) newBeverage; // setter
- (void) printDrink;
#end
#implementation Drinks
{
//THIS NEXT LINE IS WHERE I GET 4 ERRORS
- (void) startDrinking: (NSString *) newBeverage {
beverage = [[NSString alloc]initwithString:newBeverage]
}
-(void) printDrink {
NSLog(#"How is your", beverage);
}
}
#end
int main (int argc, const char * argv[]) {
Drinks *beverage = [[Drinks alloc] init];
[beverage startDrinking:#"Lemonade"];
return 0;
}
Your question is too chatty.
You missed a semi-colon in line beverage = [[NSString alloc]initwithString:newBeverage]
The line should be :
beverage = newBeverage;
and the NSLog line should be:
NSLog(#"How is your %#", beverage);
and for the declaration of method signature in header, it is followed by C and C++ . You can think of, the Compiler needs to know which functions are available first.
Your mistake is the { right below #implementation Drinks.
That's why the alignment is messed up too.
In general, if you can't find an error on the line it is reported on, just check any extraneous or missing parenthesis, brackets or braces.
The weird alignment is another clue to this.
Hope this helps. Also, like some other said, it helps if your subject is more meaningful. Not just for yourself, but also for any others that might be having a similar problem

SQLite select statement returns empty array

I am trying to fetch data from SQLite database(NSArray of strings) and populate the contents in table view cells. I tried to execute the query in command prompt and it works fine. But in code, it returns an empty array.
NSString *temp = [[NSString alloc]initWithFormat:#"select img.image from images img,illness i,illness_images ii where img.img_id=ii.img_id and i.i_id=ii.i_id and i.i_id = '%d'",illid];
const char *sqlStatement = [temp UTF8String];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)
{
// Loop through the results and add them to the array
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
// Read the data from the result row
NSString *imgname = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
[imglist addObject:imgname];
sqlite3_finalize(compiledStatement);
}
}
else{
NSAssert1(0,#"Error retrieving image names '%s'",sqlite3_errmsg(database));
}
I tried to debug and when it reaches while(sqlite3_step(compiledStatement) == SQLITE_ROW) , it does not enter the loop.
Not sure whats the mistake I am doing.
Thanks!
Try NSLog after assigning the string query to temp variable.
and check if the variable illid is giving you the correct value and run that query on the database directly.
NSString *temp = [NSString stringWithFormat:#"select img.image from images img,illness i,illness_images ii where img.img_id=ii.img_id and i.i_id=ii.i_id and i.i_id = %d",illid];
and you better release the allocated object or use class methods setting value, for memory management.
HTH.

Problem with stringByTrimmingCharactersInSet:

I'm doing a very simple trimming from a string. Basically it goes like this:
int main (int argc, const char * argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *s = [[NSString alloc] initWithString:#"Some other string"];
s = [s stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSLog(#"%#",s);
[pool drain];
return 0;
}
No matter how many times I check, I can't find a mistake on the code. But the compiler keeps returning:
Running…
2009-12-30 08:49:22.086 Untitled[34904:a0f] Some other string
It doesn't trim the string at all. Is there a mistake in my code, because I can't believe something this simple doesn't work. Thanks!
Edit:
I think I've figured my mistake. stringByTrimmingCharactersInSet only trims the string from the leftmost and rightmost ends of a string. Can anybody confirm this?
You are correct - with your code stingByTrimmingCharactersInSet will trim the left and right whitespace but leave internal whitespace alone.
Note that there's also a memory leak in your code sample:
NSString *s = [[NSString alloc] initWithString:#"Some other string"];
This will leak when you re-assign to s in the next line.

Resources