Tuesday, December 5, 2023

Optimize you working enviorenment : Single command to create & move to a directory in linux (C Shell, Bash)

Usually move to a directory just after creating is bit of a anxious task specially if the directory name is too long.

mkdir long-name-of-directory 
cd long-name-of-directory

I checked what are the shourcuts for this. specially is there an one line command to both create and move in to the directory. Actually there is no one line command. But we can create one in our shell. 

If you are using bash, following function can be added

mkcd () { mkdir "$1" cd "$1" }

If you are using csh, you have to add an alias because C shell doesn't support function.
 
alias mkcd 'mkdir $PWD/\!:1;cd $PWD/\!:1'

If you are can't configure your enviorenment we can use following commands.
 
mkdir long-name-of-directory 
cd !^ 

Let me know If you have any other solutions.

How to invoke operating system command from a C/C++ program.

There can be situations in where we need to excute a linux commands from a C++ program.

Then system() is the function you need.

It is simple, only the command has to be passed and it will return 0 if command successfuly executed, 1 otherwise.

syntax: int system(const char *command);

As system function is declared in stdlib.h, it can be considered a C function. But in C++, stdlib.h is merged into the std namespace and is located in the cstdlib .

Advantages of using an initialization list : OOP in C++

There are two different methods we can use when wtriting a constructor for a C++ class. Most of  newbies to C++ have a problem of what is the difference of these two methords or is there no difference between these two. Some people ask what does that wierd colon (" : ") syntax in the C++ construstor.

These two ways are known as constructor with an initialization list and constructor without an initialization list.



Example 1: constructor with an initialization list 

Example 2: constructor without an initialization list

Values given after the colon is known as initialization list. If there are multiple values, we can provide a comma seperated list of values as initialization list.

Example 3: initialization list of multiple values.

In first example C++ initialize property "age" with the value x where the second example initialize property "age" with it's default constructor. that means if the property is an integer value it will be initialized with an undefined value.

In first example what C++ does under the hood is,
int price = x;

In the second example it is as follows,

int price;
price = x;

Lets see what are the advantages of using an initialiation list with constructor over the none initialization list way.
  • It helps to keep the code clean and less code in constructor. So we can implement important functionalities in constructor body.
  • In above example there is no significant amout of runtime improvement. But if the age is a complex object, with a heavy construction cost there can be an advantage with runtime. 
  • If we have constant attributes in class, using initialization list is the only way of initializing those values since other ways would give errors. 


Sunday, December 3, 2023

How to identify process is listening to FIFO (Handle brocken pipe issues)

 In my previous post about named pipes, I mentioned that, "there has to be a reading process "attached" for the other side of the pipe. If you try to open pipe for writing and there is no reading process, open will hang waiting for it"

But there can be issues if reading process is killed/ternminated after attching to FIFO. In that case there will  not be any listner on the other end and writing process would give "Broken pipe" error.

In that case you could use command lsof


e.g. lsof /tmp/myfifo 
Output: 
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 
wr 64769 isurusa 3w FIFO 202,3 0t0 67668074 /tmp/myfifo 
rd 64781 isurusa 3r FIFO 202,3 0t0 67668074 /tmp/myfifo 

Obove output can be processed and make sure there is a propper listner attched to FIFO.

Below is some C++ code snipet for that.


Using named pipes (FIFO) to inter process communication (IPC) in c++

 Named pipes can be used, if you need to setup a bidirectional channel between two processes.

Traditional UNIX pipe is unnamed and it lasts only during the process lifetime, where as named pipes last as long as the system is up, beyond the life of the process.

A named pipe is basically a file and converted into a FIFO using mkfifo(). 

Then processes attach to it for reading/writing purpose. After that reading and writing can be done as on a regular file in C++.

There have to be reading process "attached" for the other side of the pipe. If you try to open pipe for writing and there is no reading process, open will hang waiting for it or return -1 with errno set to ENXIO (when O_NONBLOCK flag is used)




NOTE:

Pipes are byte-oriented, not message oriented. If you want messages, there's other IPC for that (e.g., SysV message queues).

Since it is a stream of bytes we may need to establish a minimal transport protocol (for example use '\0' byte as a delimiter, Number of bytes write/read form sender/reciever)




Thursday, November 30, 2023

Difference between 'struct' and 'typedef struct' in C++

 

In C++ there is a subtle difference between.
struct Foo { ... };
and
typedef struct { ... } Foo;

In C++ there are few types of identifiers. 
  • Constants 
  • Variables 
  • Functions 
  • Labels 
  • Defined data types 

 These identifiers are stored in different namesapces. If someone write following, he would get an compiler error.
 
struct Foo { ... }; Foo x;

That is because Foo is stored only in namespace for defined data types. 
So, everytime you need to declare an object of Foo, you need to write struct Foo x;

But with following code Foo will be defined in namesapce for variables .
 
struct Foo { ... };
typedef struct Foo Foo;

In short, It can be written as follows.
 
typedef struct Foo { ... } Foo;

So with typedef we can create objects with Foo x;
So we dont have to use struct Foo x; pattern every time we create an object of Foo.

Difference of strcpy and stpcpy in c++

The main difference is the return value of stpcpy.

stpcpy returns the pointer to the terminating \0 character of the target string. This immediately makes clear the purpose of stpcpy and the rationale behind its existence: this function is intended to be used as an intelligent replacement to strcat function in situations when you need to concatenate multiple sub-strings into one string. 
strcat works pretty poorly in such application. The problem with strcat is that it rescans the destination string every time you add something to it, thus doing lots of unnecessary work and basically generating more heat than light. For example, the following code suffers from that problem


const char *part1, *part2, *part3, *part4;
... 
char buffer[size]; /* assume that `size` is calculated properly */ 

strcpy(buffer, part1); 
strcat(buffer, part2); 
strcat(buffer, part3); 
strcat(buffer, part4);

This code can be reimplemented in a much more reasonable way by using stpcpy stpcpy(stpcpy(stpcpy(stpcpy(buffer, part1), part2), part3), part4); 

And if you don't like chained calls, you can use an intermediate pointer to store the return value of intermediate stpcpy calls
 
char *end = buffer; 
end = stpcpy(end, part1); 
end = stpcpy(end, part2); 
end = stpcpy(end, part3); 
end = stpcpy(end, part4);


Of course it is worth mentioning that strcpy and strcat are standard functions, while stpcpy is not. Refrerence : SOF

Wednesday, November 15, 2023

Handling large data sets with C++ STL vectors

 Vectors in C++ standard templat library is an dynamic container which dynamicaly allocate memory as size is increased.When  we deal with a larger data set, freaquent dynamic allocations can reduce the performance of our program.

By using the reserve() function judiciously, we can preallocate memory, reducing the need for frequent reallocations as elements are added. This not only minimizes the overhead associated with dynamic resizing but also enhances contiguous memory allocation, which can have positive effects on cache locality and iteration performance.

Let's consider an example where we have a vector that will be populated with a significant number of elements, but we also need fast random access to these elements. In such a scenario, we might strike a balance by allocating a slightly larger initial capacity than the expected dataset size using reserve(). This reduces the frequency of reallocations, optimizing memory usage.

However, it's crucial to be aware that this approach comes with a trade-off. Allocating more memory than strictly necessary increases the initial memory footprint, and if memory is a critical constraint, we might need to explore alternative solutions. 

In summary, the key is to carefully assess the specific requirements of the application and strike a balance between minimizing memory usage and optimizing for access patterns based on the characteristics of the dataset.

Basic C++ interview questions for beginners


Check if you can answer following basic questions.

1. Explain the difference between deep copy and shallow copy in C++.

2. What is a constructor, and how does it differ from a destructor in C++?

3. What is the purpose of the `virtual` keyword in C++?

4. Explain the difference between `new` and `malloc()` in C++.

5. What is a smart pointer in C++? How does it differ from a raw pointer?

6. Explain the concept of operator overloading in C++

Friday, July 23, 2021

Split a string by a given delimiter

 I was really amazed to find out that C++ string class has no split method. There are plenty of accasions I needed to split a string by a given delimiter. Lets see how to split a string and put substrings in a to vector. 

If you think incrementing varable start is ugly, you can use function find_first_not_of for it

Wednesday, June 30, 2021

modify files using sed in linux

 sed is a powerfull tool and you can find all details from here

delete a line containing a substring ("pattern")

sed -i '/pattern/d' file
replace a string
sed -e s/pattern//g -i file
using i.backup will keep a backup file of original and it is safer.  

sed -e "s/pattern//g" -i.backup file




Get parent directory name of shell script

 pwd | rev | cut -d/ -f1 | rev


lets see arguments for cut used with above command

spliting delimeter is given to -d, in this case \

required argument is given to -f, in this case 1


rev is used to reverse the string because parent directory name is the first argumet from reverse of pwd.

Get substring of a string in shell

 I wanted to get a only file names from the output of  command find . -maxdepth 1 -type d

This returns a strings contains "./" at the begining.

./1-case

./2-case

./3-case

./4-case

./5-case

./6-case


to remove first two characters i used command cut. as follows

echo "./1-case" | cut -c3-


-c means return characters

3- means from 3rd character to end


other examples

-c3 will return only 3rd character

-c3-4 will return characters form 3rd to 4th


 



Friday, June 25, 2021

Get the all folder names in current directory

 I wanted to copy a file from one location to multiple folders. We'll have to copy multiple times if we do it manally. Lets see how to use shell script to copy to every folder in one go using shell scripting.

main parts we need to do.

1. get all directories.

    find . -maxdepth 1 -type d

2. loop through every directory name, returned from 1, and copy file to each folder.

using foreach loop in s shell (.csh) 

> foreach dir ( ` find . -maxdepth 1 -type d` )
> foreach? cp ~/Scripts/convert.py $dir
> foreach? end

using for loop in bash shell (.sh)

Other commands to get all directory names

  1. ls -d */
  2. ls -l | grep `^d'

Monday, June 21, 2021

Overview of TDD and BDD

I wanted to know what are the differences between Test Driven Development and Behaviour Driven Development. So I went through many youtube videos and found following videos useful. 

Hello world of shell scripts

 

Just started recalling shell scripting again and I thought it would be good the post those somewhere.

So I started with following hello world. Not the simplest script, but it doesnt contain complex stuff. this script contains,

  • How to comment,
  • Output values using echo,
  • Execute some simple commands,
  • Assign output of a command to a variable,
  • print variable values using echo.
Just ran above script to break the inertia and get me started.

lets see some basics about shell scripting.

Most people are confused with the extension of shell scripts at the begining. some scripts have .sh extension some have .csh extension. 

I found below stackoverflow answers are nicely explained about that.


Content from link 1
bash and sh are two different shells. Basically bash is sh, with more features and better syntax. Most commands work the same, but they are different.Bash (bash) is one of many available (yet the most commonly used) Unix shells. Bash stands for "Bourne Again SHell",and is a replacement/improvement of the original Bourne shell (sh).

Content from link 2

.sh is indicative of a script for the Bourne shell (sh) or the Bourne Again shell (bash), which is generally a superset of its predecessor.

.csh is indicative of a script for the C shell (csh), which, being a shell, is largely similar, but significantly different as soon as you start doing anything much more complex than running a series of static commands.

Both shells are generally available on any POSIXy environment, and indeed both are often preinstalled, though bash (and its cousin sh) are a little more ubiquitous in my experience.

I say 'indicative' above, because the idea of a file extension doesn't technically exist and has no semantic or syntactical meaning. A file could be named script.steve or documentation.exe or include.h and still actually be a shell script. For more definitive confirmation, look at the first line of the file. For a script designed to be executed directly, it should start with a shebang line, which starts with an octothorpe (#), a bang (!), and the path to the executable which should run the script. For example:

#!/usr/local/bin/bash

or

#!/usr/bin/python3

 

Saturday, January 2, 2021

Declare const functions in cpp

 I was writting some code in c++ and I ran in to following issue with keyword const. At that point I realised that my knowledge about usage of const in C++ is very low. Here I'm writing this post with things I leaned after this mistake.

This is a simple Message class and I tried to override it's operator < so that it will be easier for sorting a container with Message objects. 


I got following error after compiling full code.


After a quick search with the help of google I found this SOF answer and according to that reason for error is, I'm calling non-const function getId which doesn't promise not to modify const Message object.

But as you can see, I had used const keyword with function getId. Guess what.. ! it is a wrong usage. It return a constant integer and return value cannot be changed. But here what I wanted is a function that gurantee calling object's safety. For that we'll have to use the const keywaord after the parameter list of function declaration.

This SOF question contains some nice explanations about the difference between const positioning with function declarations.



Saturday, May 2, 2020

Chess Puzzel - 2

This is another interesting puzzel I found in a match between Magnus Carlsen and Ian Nepomniachtchi  in Magnus Carlsen invitaional chess tournament.

This is actually a slight variation of Carlsen's end game.


Here white has the next move and don't let black to draw the match.

Anyone interested can try this in lichess using this link.



HINT: White should get queen with remainig pawn.

Chess Puzzel - 1



Recently I started to learn chess and as a part of that I practise puzzels everytime I can. So I thought it would be nice to share some interesting puzzels I found with others.


  • Can you check mate black in next 8 moves. (white has next move)
            Anyone interested can try this in lichess using this link.



Optimize you working enviorenment : Single command to create & move to a directory in linux (C Shell, Bash)

Usually move to a directory just after creating is bit of a anxious task specially if the directory name is too long. mkdir long-name-of...