Thursday, 5 November 2020

Chapter 18 // Exercise 4 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and the std_lib_facilities header provided by Stroustrup.

Chapter 18 // Exercise 4

Consider what happens if you give strdup(), findx(), and strcmp() an argument that is not a C-style string. Try it! First figure out how to get a char* that doesn't point to a zero-terminated array of characters and then use it (never do this in real - non-experimental - code; it can create havoc). 

Try it with free-store allocated and stack-allocated "fake C-style strings." If the results looks reasonable, turn off debug mode. Redesign and re-implement those three functions so that they take another argument giving the maximum number of elements allowed in argument strings. Then test that with correct C-style strings and "bad" strings.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2018/Exercise%204

My 'fake' c-style string of 'windows' reported a length of 20 and as such printed garbage after printing windows. It also didn't find 'd' in windows; it returned 'ws'. FindX returned a c-style string so strcmp turned out to work but I think that was just a fluke. That was all just in debug mode. When I switched to release it all worked properly. Visual Studio; built by wizards.

Interestingly when I examined the disassembly of the release build, the initial fake string (which was reporting a size of 8) was still being given 20 spaces:

Chapter 18 // Exercise 4 - Principles & Practice Using C++

646E6977h is "dniw" or "wind"...I'm not sure where the "ows" has gone but it's being moved into the esp register with an offset of 20. Even stranger is that after the initialisation, VS reports that Windows has 7 elements but the last 3 are garbage.

It then clears the eax register to 0 and continues assigning the rest of characters of the fake string and at esp+24 adds 'w' and 'o'. Then at esp+26 adds 's'.

The disassembly from the debug build is much more straightforward but uses more cycles:

Chapter 18 // Exercise 4 - Principles & Practice Using C++

From what I can gather here, it's storing 'w' into chars and then the rest at an offset in the ebp register. 

One day, I hope I'm as smart as the people who build compilers because this is fascinating. But anyway, the exercise still needs completing.

Instead of relying on my custom function arrayLength() to supply the length, I added an argument to strcmp, strdup and findx to take in the length of the array.


Wednesday, 4 November 2020

Chapter 18 // Exercise 3 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and the std_lib_facilities header provided by Stroustrup.

Chapter 18 // Exercise 3

Write a function, int strcmp(const char* s1, const char* s2), that compares C-style strings. Let it return a negative number if s1 is lexicographically before s2, zero if s1 equals s2, and a positive number if s1 is lexicographically after s2. Do not use any standard library functions. Do not use subscripting; use the dereference operator * instead.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2018/Exercise%203

I thought I had this in the bag by just comparing the C-style strings with < and > like you can with strings but I temporarily forgot that this only compares the first character instead. This is a problem if you have words like 'chili' and 'chilly'. So I calculated the shortest length (don't want to be accessing random memory if one of the variables is shorter than the other) and checked to see if each character was either less than the other character or equal to it. If one of them was true, continue to check, if both are false than the entire string is alphabetically after the other. I also used a bool to keep track if the first character was before as the next one may be after and that would return 1 for instances like "bra" and "zebra" as b is before z but r is after e.


Tuesday, 3 November 2020

Chapter 18 // Exercise 2 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and the std_lib_facilities header provided by Stroustrup.

Chapter 18 // Exercise 2

Write a function, char* findx(const char* s, const char* x), that finds the first occurrence of the C-style string x in s. Do not use any standard library functions. Do not use subscripting; use the dereference operator * instead.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2017/Exercise%205

I actually already did this in Chapter 17 Exercise 5, so I'm just going to link that here.

Monday, 2 November 2020

Chapter 18 // Exercise 1 - Principles & Practice Using C++

 In this exercise I am using Visual Studio 2017 and the std_lib_facilities header provided by Stroustrup.

Chapter 18 // Exercise 1

Write a function, char* strdup(const char*), that copies a C-style string into memory it allocates on the free store. Do not use any standard library functions. Do not use subscripting; use the dereference operator * instead.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2018/Exercise%201

A bit tedious and I used const_cast. This was exactly the same as exercise 4 in Chapter 17 only then we could use the subscript operator.

Sunday, 1 November 2020

Chapter 18 // Vector Drills - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and the std_lib_facilities header provided by Stroustrup.

Chapter 18 // Vector Drills

1 - Define a global vector<int> gv; initialise it with ten ints, 1, 2, 4, 8, 16, etc.
2 - Define a function f() taking a vector<int> argument.
3 - In f():
    a. Define a local vector<int> lv with the same number of elements as the argument vector.
    b. Copy the values from gv into lv.
    c. Print out the elements of lv.
    d. Define a local vector<int> lv2; initialise it to be a copy of the argument vector.
    e. Print out the elements of lv2.
4. In main():
    a. Call f() with gv as its argument.
    b. Define a vector<int> vv, and initialise it with the first ten factorial values (1, 2*1, 3*2*1, 4*3*2*1,             etc.).
    c. Call f() with vv as its argument.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2018/VectorDrills

Oh I love vector. You can just get on with your life.