Why another branch is unreachable in my code? - java

Why the output of the following code is always suck. How to get happy as the output? Why the happy branch is unreachable?
public class HowToMakeStackoverflowBetter {
private static final int HUMAN_PATIENCE = 10;
private List<Member> members = new ArrayList<>();
private int atmosphere = -10;
private Random r = new Random();
public HowToMakeStackoverflowBetter(int size) {
for (int i = 0; i < size; i++) { members.add(new Member()); }
}
public Member pick() { return members.get(r.nextInt(members.size())); }
public class Member {
private int patience = HUMAN_PATIENCE;
private Question question = null;
public Member() { patience = r.nextInt(patience+1) + atmosphere; }
public void vote(Question q) {
if (patience >= 0) {
voteUp(q);
} else {
voteDown(q);
}
}
public void ask() {
question = new Question();
for (Member member : members) {
member.vote(question);
}
}
private void voteUp(Question q) { ++q.vote; }
private void voteDown(Question q) { --q.vote; }
public String toString() {
return (question.vote >= 0)? "Happy!" : "Suck!";
}
}
public class Question { private int vote; }
public static void main(String[] args) {
HowToMakeStackoverflowBetter stackoverflow = new HowToMakeStackoverflowBetter(100);
Member me = stackoverflow.pick();
me.ask();
System.out.println(me);
}
}
After a 1000 times loop, it gives us 1000 sucks. I remember 2 or 3 years ago, this was not the case. Something changed.

Two problems. First:
linkedList::linkedList(){
*sentinel.last=sentinel;
*sentinel.next=sentinel;
sentinel.str="I am sentinel!!";
};
sentinel is your member variable, and .last is its pointer to another node. This hasn't been initialised, so trying to use it is undefined behaviour. In practice, it's effectively pointing at a random address in (or out of) memory, and you attempt to dereference the pointer then copy the entire sentinel object over the node at the imagined pointed-to address: i.e. you try to copy the 3 pointers in the sentinel node member variable to a random address in memory.
You probably want to do this:
linkedList::linkedList()
{
sentinel.last = &sentinel;
sentinel.next = &sentinel;
sentinel.str = "I am sentinel!!";
}
Secondly, you explicitly call the destructor for linkedList, which results in undefined behaviour when the compiler-arranged destruction is performed as the object leaves the stack scope it's created in - i.e. at the end of main().
I suggest you change node.str to be a std::string, as in any realistic program you'll want to be able to handle variable text, and not just point to (constant) string literals. As is, if you mix string literals and free-store allocated character arrays, you'll have trouble knowing when to call delete[] to release the memory. You could resolve this by always making a new copy of the string data to be stored with new[], but it's safer and easier to use std::string.

Since you allocated it as a local variable, your mylist will be destroyed automatically upon exiting main. Since you've already explicitly invoked its destructor, that leads to undefined behavior (attempting to destroy the same object twice).
As a quick guideline, essentially the only time you explicitly invoke a destructor is in conjunction with placement new. If you don't know what that is (yet), that's fine; just take it as a sign that you shouldn't be invoking destructors.

You forgot to initialize sentinel
In code below you are trying to initialize sentinel (which is not yet constructed) with sentinel(same thing). So you have to pass something to constructor which can be used to initialize your member variable sentinel
*sentinel.last=sentinel;
Also no need to call destructor like this. Destructor will be called once your myList goes out of scope.
myList.~linkedList();

the program may crash, with this:
*sentinel.last=sentinel;
*sentinel.next=sentinel;
sentinel is not initialized sot i has random value on stack.

You're trying to de-reference the pointers last and next of member variable sentinel when they are not yet initialized.
And these de-references *sentinel.last=sentinel *sentinel.next=sentinel are causing the crash because without assigning the values to pointers you're changing the value pointed by the pointers.
You can do like this
sentinel.last=&sentinel;
sentinel.next=&sentinel;
And as pointed out by other explicit destructor calls aren't need here.

Related

Updating original values after passing them as params to a new method instead of references

I have a method whose some parts of are repetitive. I managed to split the code in a way that the original method uses smaller methods many times. The problem is that when I pass some values as params to those new smaller methods and work with them, original values don't get updated. The actions I do are: value incrementation or removing items from arraylist. How do I update the original values using the smaller methods, not only the references? The only possible solution I came up with is to create a new class where I could have a setter for those values and update them. But are there easier/straightforward ways to solve it?
Part of the main method:
int numberOfBlocks = 0;
int currentBlock = 0;
int currentTime = 0;
ArrayList<Request> queue = new ArrayList<Request>();
if(queue.size != 0) {
updateStatus(queue, currentBlock, numberOfBlocks);
}
if(something else happens) {
removeFinished(queue, currentBlock);
}
Smaller methods:
private void updateStatus(ArrayList<Request> queue, int currentBlock, int numberOfBlocks) {
if (queue.get(0).getBlock() > currentBlock)
currentBlock++;
else
currentBlock--;
numberOfBlocks++;
}
private void removeFinished(ArrayList<Request> queue, int currentBlock){
if (queue.get(0).getBlock() == currentBlock) {
queue.remove(0);
}
}
First of all, if you pass a parameter in order for it to be changed in the method, your method should return the changed value, this will resolve your issue. If more then one value needs to be changed, then you are correct, primitives are passed y value and the invoking method doesn't see the changes made in the invoked method. So you should encapsulate those values in a wrapping class with setters and getters like you wanted to. That alone will resolve your problem. But also it would make sense for your method to return that class since it is modified. This is just a good stile
If the smaller methods are in the same class as the main method, simply don't pass them as parameters and the methods will use the class's fields. This is non-thread safe, but your class is non-thread safe already anyway.
class MyClass
{
int numberOfBlocks = 0;
int currentBlock = 0;
int currentTime = 0;
ArrayList<Request> queue = new ArrayList<Request>();
void myMainMethod() {
if(queue.size != 0) {
updateStatus();
}
if(something else happens) {
removeFinished();
}
}
private void updateStatus() {
if (queue.get(0).getBlock() > currentBlock)
currentBlock++;
else
currentBlock--;
numberOfBlocks++;
}
private void removeFinished() {
if (queue.get(0).getBlock() == currentBlock) {
queue.remove(0);
}
}

Reset each variable in java

Is there a way to reset a value of a static variable to their initial state? For example:
I have a lot of variables which holds score, speed, etc. All those variables are changing during the program execution. So when the user fails in a game, I would like to reset ALL variables to their initial state. Is there some way? Because i don't know if it is a good idea to do this manually for EACH variable in my program. for example:
static int SCORE = 0;
static float SPEED = 2.3f;
public void resetGame() {
SCORE = 0;
SPEED = 2.3;
}
Use an object, and set its initial state in the constructor:
public class GameSettings {
private int score = 0;
private float speed = 2.3F;
// methods omitted for brevity
}
...
public void resetGame() {
gameSettings = new GameSettings();
}
Also, please respect the Java naming conventions. ALL_CAPS is reserved for constants. Variables should be lowerCase.
Store the default values.
static final int DEFAULT_SCORE = 0;
static final float DEFAULT_SPEED =2.3;
static int SCORE = DEFAULT_SCORE;
static float SPEED = DEFAULT_SPEED;
public static void resetGame() {
SCORE = DEFAULT_SCORE;
SPEED = DEFAULT_SPEED;
}
Why not just recreate the object if you want it reset? Then it'll implicitly have the default values.
You could just declare your variables without values and have a method initGamestate() which sets all variables to their initial values. Call this function both on initialization of the application and when the user starts a new game.
A more object-oriented solution would be to have a class GameState which has all these variables and sets the default in its constructor. You then start every game by initializing a fresh object with new GameState();
You'll just have to reset them one by one. If you're worried about typos you could do: int initialscore = 0; int score = initialscore; and then reset them to the initial... variables in your function.
I have a lot of variables which holds score, speed, etc
You should put them all into one class and every member get initialsed (if the default won't work).
You will hold the player's state in one reference to an object of this class. To reset simply create a new object of this class and assign it to the reference.
Usually games use more than one thread (for example when using Swing or painting any graphics), e.g. so inputs are not blocked. That means with all the other solutions you might run into race conditions. This solution of Evan Knowles came closest.
I would suggest a immutable GameState class, e.g.
public GameState {
private final int score;
private final int speed;
// initial state/"reset game"
public GameState() {
score = 0;
speed = 2.3;
}
// Private so we are always in a valid state
private GameState(int _score, int _speed) {
score = _score;
speed = _speed;
}
public GameState updateSpeed(int _speed) { return new GameState(this.score, _speed); }
public GameState updateScore(int _score) { return new GameState(_score, this.speed); }
public int getSpeed() { return speed;}
public int getScore() { return score;}
// add getters, setters and whatsoever here. But watch for proper synchronization between threads!
}
The advantage here is that once the values are assigned, they can't be changed anymore ("immutable"/read-only) from the outside, so there are no concurrency issues. Plus, you get a sort of chaing for free (see below)! Moreover, you can safely (de-)serialize the game state for saving/loading games.
Effectively, each GameState represents one state in a finite state machine. Calling either updateSpeed or updateScore is a transition to a new state.
The public default constructor is a transition to the initial state of the state machine.
On a side note, the state machine is finite because the value ranges of score and speed are finite, thus all combiniations of them result in a finite amount of states.
I now assume your class for doing other game stuff is called Game.
public Game {
private volatile GameState gameState = new GameState();
public void resetGame() {
gameState = new GameState();
}
// Just an example
public increaseSpeed(int _additionalSpeed) {
gameState = gameState.updateSpeed(gameState.getSpeed() + _additionalSpeed);
}
// Change more than one value
public changeBoth(int _newSpeed, int _newScore) {
// First way: Create a new GameState, change both values step by step and then assign afterwards.
GameState _newState = gameState.updateScore(_newScore);
// other computations follow
// Do NOT assign to gameSpate here, because the state would be inconsistent then.
_newState = _newState.updateSpeed(_newSpeed);
// At the END of the method, assign the new game state. That ensures that the state is always valid
gameState = _newState;
// Second way: Use method chaining if you don't need to make other computations in between. Again, do this at the end of the method
gameState = gameState.updateScore(_newScore).updateSpeed(_newSpeed);
}
}
The volatile keyword makes sure every thread sees the same value of the gameState variable. You might want to consider using other synchronization/locking techniques instead, too. Alternatively you can make the gameState field static and skip the volatile keyword if you only have one Game object.
Because GameState is immutable(read-only), the state of your game now is always consistent/valid.
A good way is to use a static init() and call it when exception occurs.
package com.kvvssut.misc;
public class ResetStatic {
private static int SCORE = 0;
private static float SPEED = 2.3f;
private static void init() {
SCORE = 0;
SPEED = 2.3f;
}
public static void main(String[] args) {
SCORE = 100;
SPEED = 230.3f;
try {
throw new RuntimeException();
} catch (Exception e) {
init();
}
System.out.println(SCORE);
System.out.println(SPEED);
}
}

Is there any way I can return a value from a loop and continue from where I left off?

Is there any way I can return a value from a loop and continuing from where I left off ?
In the following snippet, I want to return the current value of currVm. But I am unable to do so.
In the innermost loop of the snippet :
while(c <= currVm) {
allocatedVm(currVm);
c++;
}
a function named allocatedVm is called. I want to return the value of currVm and start again from where I left off. Is there any way out ?
#Override
public int getNextAvailableVm() {
Set<String> dataCenters = confMap.keySet();
for (String dataCenter : dataCenters) {
LinkedList<DepConfAttr> list = confMap.get(dataCenter);
Collections.sort(list, new MemoryComparator());
int size = list.size() - 1;
int count = 0;
while(size >= 0) {
DepConfAttr dca = (DepConfAttr)list.get(count);
int currVm = dca.getVmCount();
int c = 0;
while(c <= currVm) {
allocatedVm(currVm); // RETURN currVm
c++;
}
count++;
size--;
}
}
}
The best approach would probably be to write a method returning an Iterable<Integer>. That's not as easy in Java as it is in languages which support generator functions (e.g. C# and Python) but it's still feasible. If the code is short, you can get away with a pair of (nested) anonymous inner classes:
public Iterable<Integer> foo() {
return new Iterable<Integer>() {
#Override public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
// Implement hasNext, next and remove here
};
}
};
}
In your case I'd be tempted to break it into a separate non-anonymous class though, just for simplicity.
Anyway, the point of using Iterable is that an Iterator naturally has state - that's its purpose, basically. So it's a good fit for your requirements.
Another rather simpler approach would be to return all of the elements in one go, and make the caller perform the allocation on demand. Obviously that doesn't work well if there could be a huge number of elements, but it would be easier to understand.
not sure i understand what you need, but:
if you wish to notify the caller of the method that you've got a value during the running of the method, but don't wish to exit the method just yet, you can use listeners.
just create an interface as a parameter to your function, and have a function inside that will have the object as a parameter.
example:
interface IGotValueListener
{
public void onGotValue(MyClass obj);
}
public int getNextAvailableVm(IGotValueListener listener)
{
...
if(listener!=null)
listener.onGotValue(...);
}
now , for calling the method, you do:
int finalResult=getNextAvailableVm(new IGotValueListener ()
{
... //implement onGotValue
};
You can return from anywhere in your method , by just putting the return keyword. If you want to put a functionality to resume ur method from different places then u need to factor ur method in that way. You can use labels and if statements, set some static variables to mark the last execution place. If your application is not multi-threaded then u need not to worry with the use of static variable synchronization. Also if your method is too big and becoming hard to follow/read, then think about breaking it into smaller ones.

Initialising a variable in the while expression - not the statement

In the expression of a while loop, is it possible to initialise a variable, then use that as part of the expression?
It's probably simpler in code:
while (int a = someMethod(), a<b)
It would be possible to just add another method, and so have to following:
private boolean whileLoopTest() {
int a = someMethod();
return a<b;
}
public void originalMethod() {
while (whileLoopTest()) {
//...
but this doesn't seem as neat.
EDIT
I also don't want to directly compare the method to my variable, as it is compared to several variable, and so if would be a long, unreadable mess. A better example of what I want would be:
while (int a = SomeClass.someStaticMethod(), -1<a && a<b)
It's not true in my case, but this would be a equally valid question if someStaticMethod() took a long time to return - I would only want to call it once.
I'm fairly new to StackOverflow, so I'm not sure if giving other situations where this would apply is what I should be doing.
int a;
while((a = someMethod()) < b){
//do something
}
A common use for this is reading from a file:
BufferedReader fileIn = ...
String line;
while((line = fileIn.readLine()) != null){
//do something
}
fileIn.close();
/edit
You can do this for your new scenario:
int a;
while(-1 < (a = SomeClass.staticMethod()) && a < b) {
//do something
}
Once the left hand portion of the && statement is executed, the return value of SomeClass.staticMethod() is stored in a, which carries over the the right hand portion of the statement.
Why not just not assign the value to "a" if you are not using it anyways?
while (someMethod() < b) { doSomething() }
If you actually do need "a" then your alternate solution would not work. The solution then would be either to save it (which I do not consider unneat) or what Kerrek said.
You can use the function directly without using a local variable like this:
while ( someMethod() < b) { /* ... */}
This, if your method returns intended value. (If you are casting it to a local variable, it's supposed to)
EDIT: For your second question.
Your concern is understandable, but if you are assigning that methods value to a local variable inside while loop's boolean expression, in every loop where "While" checks the expression, you are assigning methods' return value to local variable, which means you are calling that method in every iteration. That doesn't change anything from my first answer.

Java bug or feature?

Ok, here is the code and then the discussion follows:
public class FlatArrayList {
private static ArrayList<TestWrapperObject> probModel = new ArrayList<TestWrapperObject>();
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int [] currentRow = new int[10];
int counter = 0;
while (true) {
for (int i = 0; i < 10; i++) {
currentRow[i] = probModel.size();
}
TestWrapperObject currentWO = new TestWrapperObject(currentRow);
probModel.add(counter, currentWO);
TestWrapperObject testWO = probModel.get(counter);
// System.out.println(testWO);
counter++;
if (probModel.size() == 10) break;
}
// Output the whole ArrayList
for (TestWrapperObject wo:probModel) {
int [] currentTestRow = wo.getCurrentRow();
}
}
}
public class TestWrapperObject {
private int [] currentRow;
public void setCurrentRow(int [] currentRow) {
this.currentRow = currentRow;
}
public int [] getCurrentRow() {
return this.currentRow;
}
public TestWrapperObject(int [] currentRow) {
this.currentRow = currentRow;
}
}
What is the above code supposed to do? What I am trying to do is load an array as a member of some wrapper object (TestWrapperObject in our case). When I get out of the loop,
the probModel ArrayList has the number of elements it is supposed to have but all have the same value of the last element (an array of size 10 with each item equal to 9). This is not the case inside the loop. If you perform the same "experiment" with a primitive int value everything works fine. Am I missing something myself regarding arrays as object members? Or did I just encounter a Java bug? I am using Java 6.
You are only creating one instance of the currentRow array. Move that inside the row loop and it should behave more like you expect.
Specifically, the assignment in setCurrentRow does not create a copy of the object, but only assigns the reference. So each copy of your wrapper object will hold a reference to the same int[] array. Changing the values in that array will make the values appear to change for all other wrapper objects that hold a reference to the same instance of the array.
i don' t want to sound condescending, but always try to remember tip #26 from the excellent pragmatic programmer book
select isn't broken
it is very rare to find a java bug. keeping this in mind often helps me to look over my code again, turn it around, and shake out the loose bits until i finally discover where i was wrong. of course asking for help early enough is very encouraged, too :)

Categories

Resources