Skip to content

Instantly share code, notes, and snippets.

@barrysteyn
Last active January 22, 2023 22:43
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save barrysteyn/9fbd5ebd0719629223f9 to your computer and use it in GitHub Desktop.
Save barrysteyn/9fbd5ebd0719629223f9 to your computer and use it in GitHub Desktop.
C/C++ Examples For Understanding

Introduction

These toy examples are for helping with understanding C/C++. There is an excellent C++ samples site which demonstrates many useful things.

#include <stdio.h>
#include <stdlib.h>
void func(int* b) {
b = (int*)malloc(sizeof(int)); //What is malloc? Why can't I use new? What's the difference
*b = 400;
printf("%d\n", *b); //What will print here
}
int main() {
int* a = 0;
func(a);
printf("%d\n", *a); //Error - but why? Also, is there a memory leak?
}
//This example follows on from example1.c
#include <stdio.h>
#include <stdlib.h>
void func(int **b) {
*b = (int*)malloc(sizeof(int));
**b = 400;
printf("%d\n", **b); //What will print here
}
int main() {
int **a = (int**)malloc(sizeof(int*));
func(a);
printf("%d\n", **a); //Why does this work?
}
//Ahhhh sanity! This example follows from example 1 and example 2.
//Notice how much neater it is
#include <iostream>
using namespace std;
void func(int*& b) {
b = new int;
*b = 400;
}
int main() {
int * a;
func(a);
cout << *a << endl; //Why does this work?
}
//Constructors and destructors without move constructor
#include <iostream>
using namespace std;
class X {
private:
int num;
public:
//Default constructor
X() : num(0) {
cout << "Default Constructor" << endl;
}
//Overloaded constructor
X(const int& val) : num(val) {
cout << "Overloaded Constructor: Setting num to " << val << endl;
}
//Copy constructor
X(const X& lVal) {
this->num = lVal.num;
cout << "Copy Constructor" << endl;
}
//Copy assignment constructor
X& operator=(const X& lVal) {
this->num = lVal.num;
cout << "Copy Assignment Operator"<<endl;
return *this;
}
//Destructor
~X() {
cout << "Destructor"<<endl;
}
};
X doSomething() {
X x(100);
return x;
}
int main() {
cout << "x1:"<<endl;
X x1 = doSomething();
cout << "x2:"<<endl;
X x2;
x2 = doSomething();
}
// Rule of 5 and Move constructor example
// We will use char* here on purpose (instead of say string)
// Also, this example DRYs the code as much as possible. Can you spot where?
#include <iostream>
using namespace std;
class X {
private:
int test;
char* str;
public:
//Default constructor
X() : str(NULL) { cout << "Default Constructor" << endl; }
//Copy constructor
X(const X& lVal) : X(lVal.str) { cout << "Copy Constructor" <<endl; }
//This is the copy assignment operator
X& operator=(const X& lVal) { cout << "Copy assignment operator" << endl; return *this = lVal.str; }
//Destructor
~X() { cout << "Destructor" << endl; if (str) delete[] str; }
//Move constructor
X(X&& rVal) {
cout << "Move constructor" << endl;
this->str = rVal.str; //Shallow copy
rVal.str = NULL; //Important - set to null otherwise rVal destructor will destroy heap
}
//----- Rule Of "5" Ends Here -----//
//Overloaded constructor
X(const char* lVal) : X() {
cout << "Overloaded constructor: X(const char* lVal)" << endl;
*this = lVal;
}
//Assignment operator (Note: This is not the copy assignment operator)
X& operator=(const char* str) {
cout << "Assignment operator overloaded operator=(const char* str) " << str << endl;
if (this->str) delete [] this->str;
this->str = new char(strlen(str));
for(int i=0; str[i]; this->str[i] = str[i], i++); //Deepcopy - done explicitly here as an example to contrast from shallow copy in move constructor
return *this;
}
const char* getStr() const { return this->str; }
};
X retByVal() {
return X("Hello World");
}
int main() {
X x4(retByVal());
return 0;
}
@rodrigoruiz
Copy link

But what is the practical different between "s1 = s2" and "s4 = s1"?
To me they basically do the same thing, copy content from one string to another.
Why do I even need to know that underneath there are two different methods being called?
Is there any reason to actually implement those two methods in different ways?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment