My exploration with C and C++.
C shells by the sea shore, buffer overflow by adding more?
Table of Contents:
Sections | Description |
---|---|
Links | External references |
Better Usage | Usage mistakes explained and corrected |
Tools | A list of compilation and debugging tools |
Notes | A list of notes I've made on C and C++ programming |
Refer to the main-args.cpp to test out this explanation.
Global
getline()
works with C++std::string
objects
std::cin.getline()
from<istream>
works with classic C strings i.e. pointers to char.
cin
reads a word e.g. digits/chars separated by whitespace.
std::getline(std::cin, char a);
gets the whole line from user and stores ina
.
cin.get(char a, streamsize n);cin.get();
gets the whole line (stores ina
), then takes in end-of-line character. Repeat this to get a the next line.
cin.get(char a, streamsize n)
gets the whole line (stores ina
), but repeating this line gives no more input.
the
>>
operator ofstd::istream
reads space separated strings
stringstream()
: converts strings of digits into ints, floats or doubles.atoi()
: Only works on C-style strings (character array and string literals).stoi()
: C++ 11 only compatible and works for both C++ strings and C style strings.
One of the shortcuts listed in the above link:
sizeof( myArray )
is total number of bytes allocated for that array.sizeof( myArray[0] )
is the number of bytes for one element.
sizeof( myArray ) / sizeof( myArray[0] )
is the number of elements in the array.
e.g. when using a function above/before where it was defined in the script.
e.g. C++
static_cast<int>(x)
vs C(int)x
e.g.
round(0.5)
becomes1
Mistakes on Usage Explained and Resolved.
Suppose you have a file.txt
with the following content:
1
Your main.cpp
file is of the following:
#include <iostream>
#include <fstream>
int main(int argc, char const *argv[])
{
std::ifstream input_file( argv[0] );
while( !input_file.eof() )
{
int num;
//storing value
std::cin >> num;
// printing value
std::cout << num;
}
}
After compilation, loops happen when:
(1) ./a.out < file.txt
(2) ./a.out file.txt
Reasons:
(1) End of File is never reached. cin
keeps storing the content from the file,
and cout
keeps printing onto the terminal. Due to the < file.txt
portion, a
file is never fed into the program. The reason for this is:
./a.out < file.txt
is considered as only1
argument i.e../a.out
; Fixingargv[0]
toargv[3]
does not work because doing< file.txt
is being utilised bycin
.
(2) End of File is never reached. Although 2
arguments are fed into the
program, i.e. ./a.out
and file.txt
, file file.txt
was never opened:
Nothing happens when the program runs, since there was no file opened. Adding a boolean check like with
input_file.is_open()
could be useful to see if the file was successfully opened.First,
std::ifstream input_file( argv[0] );
should be corrected tostd::ifstream input_file( argv[1] );
.argv[0]
is actually refering to./a.out
so havingargv[1]
refers tofile.txt
.Note: having
argv[1]
unchanged, will show that the file is opened when usinginput_file.is_open()
becausea.out
itself is a file.Second, regardless of whether the above fix was made, the program now waits for a user's input from
cin
. This loops forever, and will proceed to ask for a user's input forever (only if an int/number was given). If an anything other than a number was given, an infinite/forever loop of zeros will show.The infinite loop happens, because this program never reaches the end of files
argv[1]
orargv[0]
.
Use the constructor and let its destuctor do the work of opening and closing the file. source
// if this is done:
std::ifstream input_file( argv[0] );
// Then the following is unnecessary:
//
// close the file when parsing is done
std::ifstream input_file;
input_file.Open(argv[0]);
input_file.close();
Compiler Versions
gcc (GCC) 10.2.1 20200723 (Red Hat 10.2.1-1)
gcc (Ubuntu 5.5.0-12ubuntu1) 5.5.0 20171010
General command to compile:
gcc -Wall filename.c -o filename
Since,
gnu18
GNU dialect of ISO C17 is the default for C code.
Use
-std=c99
flag for the C99 standard.
And,
gnu++14
gnu++1y
GNU dialect of
-std=c++14
is the default for C++ code.gnu++1y
is deprecated.
-
Use
g++
for.cpp
, seegcc
vsg++
discussion. -
See this detailed guide on how to install, compile and use a
makefile
.
Debugging Tools
GNU gdb (GDB) Fedora 9.1-6.fc32
GNU gdb (GDB) 8.1
Error encountered during usage on Mac OSX:
Unable to find Mach task port for process-id 7234: (os/kern) failure (0x5). (please check gdb is codesigned - see taskgated(8))
To resolve issue above:
Link to the related Github Issue
- This more reader friendly, as in not txt file print but the content mentioned in the above link was copied from this.
- The work around "the bug" that this link is referring to can be found here.
How I resolved this::
Before creating the certificate, check the version of gdb by doing
gdb --version
.
- if it is not version 8.0.1, then do the following:
- Run
brew uninstall gdb
, if that doesn't work then do,brew uninstall --force gdb
. Doingbrew unlink gdb
may work instead, look at this discussion.- Now do
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/c3128a5c335bd2fa75ffba9d721e9910134e4644/Formula/gdb.rb
.For more information on the above, refer to this on StackOverFlow.
The following are steps to codesign gdb:
- In Keychain Access (toolbar i.e. where system time is displayed), go to Certificate Assistant and Create a Certificate.
- Enter a relatable name for this Certificate e.g. "gdb_cert".
- Fill in the following and then click create:
- Identity Type: Self Signed Root
- Certificate Type: Code Signing
- Double click on the Certificate which can be found in "Login" category.
- In the popup window, click on the "Trust" arrow and select "Always Trust" when using this Certificate.
- Drag this Certificate from the Login category to "System".
- Run
killall taskgated
:
- if
No matching processes belonging to you were found
then dops aux | grep taskgated
- Finally run
codesign -fs nameofcertificate /usr/local/bin/gdb
:
- To find path location of gdb run
which gdb
- This command does not need to be in the same directory of the Certificate
- Restart machine.
- Additional sources:
This may happen:
(gdb) file a.out
\"a.out\": not in executable format: File format not recognized
Do
g++ -m32 filename.cpp -g -Wall
to resolve, as noted here, existing GDB installed may be the x86_32 version.
valgrind-3.13.0
These are links to a separate README.md.