What's the difference between release(), reset(), and std::move on a unique_ptr?
release() gives up ownership without deleting and returns the raw pointer (you must delete it). reset()deletes the owned object now. std::movetransfers ownership to another unique_ptr (which will delete it); the source becomes null.
delete first calls the destructor, then frees the memory (via operator delete, usually free). free only frees the raw memory — no destructor. So delete = destructor + free; free = free only.
What is the difference between static Logger L; and static Logger* P = new Logger(); at program exit?
L is destroyed at exit, so ~Logger() runs. With P only the pointer is static; the Logger object is on the heap, so its destructor never runs and the memory is not freed by your code.
True or false: in well-formed code, a reference can be null.
False. A reference must be bound to an existing object when it is declared, and it cannot be reseated, so there is no null reference. Use a pointer when "nothing" is a valid value.
Base has a non-virtual destructor — what happens when delete b; runs?
C++
struct Base { ~Base(){} }; // non-virtual!struct Derived : Base { /* owns memory */ };
Base* b = newDerived();
delete b;
Only ~Base() runs. delete b goes through a Base* whose destructor is non-virtual, so it uses static dispatch and ~Derived() is never called — anything Derived owns is leaked (the standard calls this undefined behaviour). To make it correct, declare the base destructor virtual (virtual ~Base();); then delete b runs ~Derived() first, then ~Base().
whoami prints just your username. id prints your numeric UID, primary GID, and all group memberships. That extra detail is what matters for permissions, because the kernel checks those numeric IDs (not the name) against a file's owner/group to decide which rwx triplet applies to you.
What does an overloaded operator-> return, and what does the compiler do with it?
It returns a pointer. The compiler then applies the real -> to that returned pointer to reach the member — so w->print() becomes w.operator->()->print(). (If it returned another wrapper, -> keeps chaining until it hits a raw pointer.)
In what order are the base and derived parts constructed and destroyed?
Construction: base first, then derived — the base subobject must be fully built before the derived part relies on it. Destruction: the reverse — derived first, then base. A derived object physically contains the base subobject laid out first.
Why does paging cause internal fragmentation but eliminate external fragmentation?
Paging places each page into any free frame, so there are no unusable gaps between allocations → external fragmentation is gone. But a region rarely fills a whole number of pages, so the last page of each region is usually only partly used — the remainder is wasted inside that frame → internal fragmentation (bounded by page size − 1). It trades a large, scattered waste for a small, predictable one.
Meters(double) is a non-explicit single-argument constructor, so the compiler silently converts 3.5 into a Meters to call twice. 3.5 × 2 = 7 (printed as 7).
True or false: marking a shared counter volatile makes ++counter safe to call from two threads.
False.volatile only stops the compiler from optimizing the reads and writes away. ++counter is still a read-modify-write that two threads can interleave. Use std::atomic<int> or a mutex.
reserve(10) allocates room for at least 10 elements but adds none, so after two push_back calls size() is 2 while capacity() is still at least 10 (true prints as 1).
This version returns Counter by value instead of by reference. What does it print now?
C++
struct Counter {
int n = 0;
Counter add(int k) { n += k; return *this; } // returns a copy
};
intmain() {
Counter c;
c.add(1).add(2).add(3);
std::cout << c.n;
}
Returning *thisby value hands back a copy. Only the first add(1) changes c; .add(2) and .add(3) change temporary copies that are thrown away. So c.n is 1.
True or false: a static member function can read the object's non-static data members.
False. A static member function has no this, so there is no object to read from; it can only use static members (or an object passed in). g++ rejects it.
An array must be contiguous. Where is that actually guaranteed?
In virtual address space.arr[i] is computed from virtual addresses, so they must be continuous. The physical frames behind the pages can be scattered; the page table maps them.
An invariant is a rule that must always be true for a valid object — e.g. a BankAccount's balance must never be negative. By keeping balance private and only changing it through deposit()/withdraw(), each of which checks the rule, the invariant is guaranteed after every operation, so the object is never left inconsistent.
Why does C++ leave operator[] unchecked by default?
Because of the principle 'don't pay for what you don't use' — a bounds check on every element access adds a comparison that's costly in tight numeric loops, so [] is fast and trusts the programmer. (Java/Python bounds-check always: safer, but you pay on every access with no opt-out.) C++ gives you both: fast [] when you've verified the index, and checked .at() when you want the safety net.
Yes. A pointer is just a multi-byte integer (8 bytes on 64-bit) that holds an address, so it's stored in the machine's endianness — little-endian on x86, meaning its bytes appear reversed in a raw memory dump, exactly like any int.
External fragmentation. A process no longer needs one big contiguous block of RAM, because any free frame can hold any page. (Paging can cause a little internal fragmentation in the last page.)
Which direction does the stack grow, and where is its 'top'?
On typical machines the stack grows downward, toward lower addresses — each call/pushdecrements the stack pointer. So the 'top of stack' (the most recent item) is actually at the lowest address currently in use, the opposite of the everyday picture of a stack growing up.
Values start at 0 and count up from the last assigned one: Low is 0, Mid is set to 5, so High is 6. A plain enum converts to int implicitly, so cout prints the numbers.
What is the difference between size() and capacity()?
size() is how many elements are currently stored. capacity() is the total number of slots currently allocated before the vector must reallocate. The spare room is capacity() - size(); always capacity() >= size().
Which of these are true of a page fault? Select all that apply.
A page fault is normal: the OS loads the missing page and restarts the instruction. A major fault needs a disk read (a minor one doesn't). It is not a bug and not a segfault, which is an illegal access the OS refuses.
What is the difference between the copy constructor and copy assignment?
The copy constructor builds a brand-new object from an existing one (T b = a;). Copy assignment (operator=) is used when both objects already exist (b = a;): it must free its own old resource, deep-copy, guard against self-assignment, and return *this.
Why prefer an initializer list over assigning members inside the constructor body?
The init list constructs each member once, directly with the right value. Assigning in the body first default-constructs the member, then overwrites it — two steps, wasteful for non-trivial types, and outright illegal for const/reference members. So the init list is both faster and more capable.
If you can't instantiate an abstract class, what CAN you do with it?
You use pointers or references to it — that's the whole point of an abstract base: Shape* s = new Circle();. As long as the derived class (Circle) overrides every pure virtual, it's concrete and can be created, and you manipulate it polymorphically through the abstract base pointer/reference.
With 4 KB (4096-byte) pages, virtual address 12290 is in which page, and at what offset?
12290 = 3 × 4096 + 2, so it is page 3, offset 2. The page number goes through the page table to find the frame; the offset is kept as-is inside that frame.
Why is returning the address of a local variable a bug?
The local lives in the function's stack frame, which is reclaimed when the function returns. The returned address then points to memory that's no longer valid — a dangling pointer — so using it is undefined behaviour.
When you access a file, how does the kernel decide which of the three rwx triplets to apply?
The three triplets are for the file's owner, its group, and others. On each access the kernel checks your process's UID/GID: if you're the owner it uses the owner triplet; else if you're in the file's group, the group triplet; else the others triplet. Exactly one triplet applies — chosen most-specific-first — and it decides whether your requested r/w/x is allowed.
If C++11 lets you write int a = 0; at the declaration, why is the init list still needed?
A default member initializer is a fixed fallback, same for every object, and can't use constructor arguments or initialize a base class. The list is needed for argument-driven values and for base class initialization.