Wednesday, February 8, 2012

Friday, December 9, 2011

Thursday, May 12, 2011

Copy constructor & Assignment constructor

Default copy
Every struct and class have a default copy constructor and assignment operator method. e.g.
1: struct Foo { int f, o; };
2: Foo f1 = {1, 10};
3: Foo f2(f1);
4: Foo f3; f3 = f1;
Line 2 invokes the default copy constructor; Line 3 invokes the default assignment operator. The difference of the two is that the copy constructor is invoked when the target (f2) is constructed, passing the source object into the new one; the assignment constructor is invoked when the target object (f3) already exists.
When to implement your own copy?
The default copy only make a shallow copy. Thus, if one of the members is a pointer, a shallow copy will not allocate memory but create another pointer pointing to the same address. When one of them free the memory, the other one is still pointing to that piece of memory.
In this case, explicit copy and assignment constructor are required.
The difference between the bodies of the two constructors is that the copy constructor can allocate new memory and assign value to the pointer assuming that no member has been set yet (since the object is just being constructed); however, the assignment constructor must handle the case where members may already have been initialized and thus have to delete the contents of the pointer before assigning new value.
class Foobar {
int fo; char* name;
public:
Foobar(const char* str, int n) {
name = new char[strlen(str)+1];
strcpy(name, str);
age = n;
}
Foobar(const Foobar& rf) {
name = new char[strlen(rf.name)+1];
strcpy(name, rf.name);
age = rf.age;
}
Foobar& Foobar(const Foobar& rf) {
char* temp = new char[strlen(rf.name)+1];
delete[] name;

name = temp;
strcpy(name, rf.name);
age = rf.age;
return *this;
}
~Foobar() { delete[] name; }
};
Notice that
  • why temp is used and why not delete[] name; name = new char ...The reason is that the new may throw an exception and leave the object in a bad state. By finishing all operations that could fail and then replacing the fields, the code is safe.
  • the assignment operator returns a reference to the object so that f1 = f2 = f3 will work.
Avoid copy or assignment constructors
In some cases, it may not be proper to make a copy of some class fields. To prevent the default implicit copy and assignment constructors, a private copy constructor and assignment operator should be provided. No need to implement the methods. Simply prototyping is enough.
private:
Foobar(const Foobar& rf);
Foobar& Foobar(const Foobar& rf);
By doing this, if a piece of code attempts to copy the object, there will be an error message saying that the copy constructor and assignment operator cannot be accessed.

Saturday, April 23, 2011

Mac OS X Memory Management: terms in Activity Monitor

Last week, I was suffered by the super slow start of VMware Fashion. From the status bar, I can see the usage of CPU is low and the problem seems from memory usage. I opened Activity Monitor to see the detailed memory usage and was surprised to find out that there are only 100MB (or even less!) "free memory". Btw, I am using Macbook with 2G memory.
This forced me to do more research about the memory management in Mac OS. It turned out that the low amount free memory may not be a bad thing (cf. in Windows, it definitely sucks!).
Let's start from some general terms here.
You might noticed that, in Activity Monitor, there are: Free, Wired, Active, and Inactive memory. The sum of all these four will be equal to the total amount of RAM (in my case, 2GB).
  • Free memory: as named, it is the not-yet-used memory.
  • Wired memory: here, "wired" = always-in. These data will never be moved to the disk and will always stay in RAM. It could be owned by some core system processes or stand-by processes even after you close the application (main process).
  • Active memory: These data is currently in RAM and has been recently used.
  • Inactive memory: here is the tricky part. These data is not actively being used but has recently used. What does it mean? It means that each time when you quit an app, their data will stay in the memory as inactive memory until the app is reopened and access the same data again, OR they are replaced by other apps' data just like free memory. What's the benefit? Think about "memory frequency"!
Mac OS uses a different memory management methodology from what Windows does. It will crawl as more as possible free memory to catch up disk data so that when these data come into use, the access time will be reduced. When the memory usage hits some threshold, it will release some inactive memory; If it is still not enough, it will swap some data from RAM to disk. In Activity Monitor, you can see the cumulative statistics of Page-ins and Page-outs.
Check out this for more details about memory management and virtual memory.

Tuesday, March 15, 2011

求二进制数中1的个数

比较常见的就是移位计数和快速法了,这篇帖子里列的相当全。

Friday, March 11, 2011

GNU Screen

If you are a UNIX user, you maybe familiar with workspaces, featured in UNIX where you can have different workspaces: one for reading email, one for working, one for Internet surfing, and one for composing documents, blablabla.
Now you can start one terminal and run screen in it. Bang! Problem solved.
Here are some commands most used:
  1. typing screen will start a screen session for you;
  2. Ctrl-a and then type c to create a new session;
  3. Ctrl-a n to switch to the next or previous session;
  4. Ctrl-a d to detach from screen sessions and screen -r [session number] to resume the session you detached. Note that after you detached, all of the screen windows are still running. You can close the terminal, leave your office, go back home, open a terminal on your home machine and resume your work at home!

Sunday, February 27, 2011

How to run .py file?

Suppose Python is installed in /usr/bin/python.
  1. In the .py file, add the following line as the first line to tell shell which interpreter you are using:
    #!/usr/bin/python
  2. Close the file, set it as an executable file
    chmod a+x [filename]
  3. Now you can type ./[filename] to execute it!
What if we need some input parameters? We will use command-line arguments and here is how:
In the .py file, add import sys, and then grab the arguments from sys.argv[1:].
Note 1: sys.argv[0] is the script name.
Note 2: sys.argv read in arguments as strings, so if you want integer or float use int() or float() to convert them.

Friday, February 25, 2011

Python - list

List is a very useful and powerful data structure in Python. Here are something about it.
Copy a list in a right way
First we need to understand how Python manages objects. Remember pointers in C++? Keep it in mind since you gonna see its bro soon.
In Python, a = [1, 2, 3] means that a POINTs to the list [1, 2, 3]. a itself is NOT the list.
So, if we do b = a, we didn't copy the list from a to b. We just created a new "pointer" (or, more pythonic, say "tag") b which points to the same object as a does.
Thus, to copy the list referenced by a, we need to create a new list and attach b to it.
There are two ways:
  1. Slicing. i.e. b = a[:]
    [:] returns a slice of the specified portion of the list. It creates a new list, and copy the portion of the original list into the new one. By omitting the first and second index, the slice starts at the beginning and stops at the end of the list.
  2. Constructor. i.e. b = list(a)
    Here, list() is the constructor of list. It will construct a new list based on the passed parameter.
    Plus, this makes the code more readable and more OO styled!
Refer [1] for more details.
More stuffs about [start:stop]
Basically, you can get any continuous portion from the original list by using the operator [:].
But, what if we want to extract odd or even items?
The straightforward way is even = [lst[i] for i in range(len(lst)) if i % 2 == 0].
Wait! Try this.
>>> l = [1, 2, 3, 4, 5]
>>> l
[1, 2, 3, 4, 5]
>>> l[::2]
[1, 3, 5]
>>> l[1::2]
[2, 4]
See, it is simple! The secret is: the third arg is a step value.
Remove duplicates from a list
[2] lists many ways to do it and their benchmarks. I pick some of them:
  1. list(set(lst)) # No order preserving
  2. {}.fromkeys(lst).keys() # No order preserving (faster than 1)
  3. seen = set() # Order preserving
    [x for x in lst if x not in seen and not seen.add(x)]

How to "re-import" an updated module in Python Interpreter

It is common to write a module and debug and test it in the Python interpreter on-the-fly. Then, after fixing some bugs, we want the interpreter test on the updated module.
Just typing "import" again will not help since it would only give you the existing copy of the module from sys.modules. Thus, a straightforward but brutal (and annoying :) way is exiting-and-reentering the interpreter.
Or, we can use "reload(module)" to update sys.modules and get a new copy of that module.
reload is a build-in function in Python. When reload(module) is executed:
  • Python modules’ code is recompiled and the module-level code reexecuted, defining a new set of objects which are bound to names in the module’s dictionary. The init function of extension modules is not called a second time.
  • As with all other objects in Python the old objects are only reclaimed after their reference counts drop to zero.
  • The names in the module namespace are updated to point to any new or changed objects.
  • Other references to the old objects (such as names external to the module) are NOT rebound to refer to the new objects and must be updated in each namespace where they occur if that is desired.
Did you see it? It is very tricky to get it right! If, if any other modules have a reference to the original module or any object from the original module, they will keep their old references and very confusing things will happen.
So, if you are using a self-contained module, reload will be perfect for you to save you from exiting-reentering cycles; but if you got two modules depending on each other, or if you got a module passing references to its objects to system module, unfortunately, exiting-reentering would be the only choice for you.

Thursday, February 24, 2011

Vi/Vim: Insert text at the beginning of a multi-line selection

Sometimes, we would like to indent or comment out a block of code. Here are some solutions:
Solution 1:
  • Use Ctrl+v to select the first column of text in the lines you want to comment.
  • Then hit 'I' and type the text you want to insert.
  • Then hit Esc, wait 1 second and the inserted text will appear on every line.
Solution 2:
  • This replaces the beginning of each line with "//":
    :%s!^!//!
  • This replaces the beginning of each selected line (use visual mode to select) with "//":
    :'<,'>s!^!//!;
    And removing the text goes as follows:
    :'<,'>s!^//!!
  • If you want to reuse it, put this in your .vimrc:
    vmap \c :s!^!//!
    vmap \u :s!^//!!

    Then, whenever in visual mode, you can hit \c to comment the block and \u to uncomment it. Of course, you can change those shortcut keystrokes to whatever.
Solution 3:
  • place the cursor on the first line and type the following to insert "//" at the beginning of that line:
    I//
  • Press Esc and use the digraph:
    j.j.
    Here, j is a motion command and . repeats the last editing command you made (in this case I//).