2022-06-20 C++Demo

include <iostream>

include "GL3TestCase.h"

include "TestCase.h"

include <string>

include <vector>

include <memory>

include <unordered_set>

include<stdio.h>

include<string.h>

include<stdlib.h>

include<unistd.h>

include<pthread.h>

include <map>

include "texture_external.glsl"

include <thread> // std::thread

include <atomic> // std::atomic, std::atomic_flag, ATOMIC_FLAG_INIT

using namespace deqp;
using namespace tcu;
using namespace std;

include <iostream>

include <vector>

char *thread_func1(void *arg) {
pid_t pid = getpid();
pthread_t tid = pthread_self();
printf("%s pid: %u, tid: %u (0x%x)\n", (char *) arg, (unsigned int) pid, tid, tid);

char *msg = "thread_func1";
return msg;

}

void *thread_func2(void *arg) {
pid_t pid = getpid();
pthread_t tid = pthread_self();
printf("%s pid: %u, tid: %u (0x%x)\n", (char *) arg, (unsigned int) pid, tid, tid);
char *msg = "thread_func2 ";
while (1) {
printf("%s running\n", msg);
sleep(1);
}
return NULL;
}

//int main_thread() {
// pthread_t tid1, tid2;
// if (pthread_create(&tid1, NULL, (void *) thread_func1, "new thread:") != 0) {
// printf("pthread_create error.");
// exit(EXIT_FAILURE);
// }
//
// if (pthread_create(&tid2, NULL, (void *) thread_func2, "new thread:") != 0) {
// printf("pthread_create error.");
// exit(EXIT_FAILURE);
// }
// pthread_detach(tid2);
//
// char *rev = NULL;
// pthread_join(tid1, (void *) &rev);
// printf("%s return.\n", rev);
// pthread_cancel(tid2);
//
// printf("main thread end.\n");
// return 0;
//}

/**

  • 不使用,virtual 虚析构函数的话,会造成向上转型为基类,析构基类时不知道自己有子类,导致子类内存泄漏。
    */
    class A : public enable_shared_from_this<A> {
    public:
    A() { std::cout << " A "; }

    virtual ~A() { std::cout << " ~A "; }

    int *data;

    int operator() const { return data; }

    std::shared_ptr<A> getSharedPtr() {
    return shared_from_this();
    }

    virtual void f() {
    std::cout << "a\n";
    }
    };

class B : A {
public:

B() { std::cout << " B "; }

~B() { std::cout << " ~B "; }

void f() override { // 'override' 可选
    std::cout << "b\n";
}

};

class C : B {
public:

C(const char *chars) { std::cout << " C "; }

~C() { std::cout << " ~C "; }

void f() override { // 'override' 可选
    std::cout << "c\n";
}

};

void test_virtual() {
{
B *b = (B *) new C("cc");
delete b;
}

std::cout << " end\n";

B b;
b.f();

C c("cc");
c.f();

B *b_c = (B *) &c;
b_c->f();

int *data;
{
    A a;
    a.data = new int[4]{99, 111, 222, 444};
    data = (*a);
}

printf("1  %d %d \n", data[0], data[1]);

}

//走了默认的赋值copy构造
void test_default_copy() {
A a;
A aa;
a.data = new int[4]{99, 111, 222, 444};
aa = a;

printf("1  %s %p %p %d\n", aa.data, &(aa.data), aa.data + 1, aa.data[0]);
printf("2  %s %p %p %d\n", a.data, &(a.data), a.data, a.data[0]);
//一个int占用 4字节

// 1 c 0x7ffeee5860c8 0x7facb7402cf4 99
// 2 c 0x7ffeee5860d8 0x7facb7402cf0 99
}

enum ObjectType {
NO_OBJECT,
OBJECT_JS,
OBJECT_NATIVE,
END
};

template<typename T>
struct template_class {
T *data;
};

void test_template() {
template_class<int> t1{};
t1.data = new int[8];
t1.data[0] = 99;
printf("test_template %d %d \n", t1.data[0], t1.data[1]);
ObjectType a = ObjectType::OBJECT_NATIVE;
ObjectType b = a;
ObjectType c(b);

printf("test_template ObjectType   %d %d %d \n", a, b, c);

}

class Intvec {
public:
explicit Intvec(size_t num = 0)
: m_size(num), m_data(new int[m_size]) {
log("constructor ", m_size);
}

~Intvec() {
    log("destructor");
    toString();
    if (m_data) {
        delete[] m_data;
        m_data = nullptr;
    }
}

Intvec(Intvec &&other) {
    log("move constructor && ");
    m_size = other.m_size;
    m_data = other.m_data;
    other.m_data = nullptr;
    other.m_size = 0;

}

Intvec(const Intvec &other)
        : m_size(other.m_size), m_data(new int[m_size]) {
    log("copy constructor");
    for (size_t i = 0; i < m_size; ++i)
        m_data[i] = other.m_data[i];
}

//
Intvec &operator=(Intvec &other) {
log("copy assignment operator &");

    Intvec tmp(other);
    std::swap(m_size, tmp.m_size);
    std::swap(m_data, tmp.m_data);

// why!!!
// std::swap(m_data, other.m_data);
return *this;
}

Intvec &operator=(const Intvec &other) {
    log("copy assignment operator const &");

    Intvec tmp(other);
    std::swap(m_size, tmp.m_size);
    std::swap(m_data, tmp.m_data);

// why!!!
// std::swap(m_data, other.m_data);
return *this;
}

//
Intvec &operator=(Intvec &&other) {
log("move assignment operator && ");

    std::swap(m_size, other.m_size);
    std::swap(m_data, other.m_data);
    return *this;
}

public:
void log(const char *msg) {
cout << "[" << this << "] " << msg << "\n";
}

void log(const char *msg, int count) {
    cout << "[" << this << "] " << msg << " " << count << "\n";
}

void toString() {
    cout << "----toString  " << this << " Intvec[" << this->m_data << "] " << this->m_size << "\n";
}

size_t m_size;
int *m_data;

};

void modify_intvec(const Intvec *intvec) {
// intvec->m_data = new int[10];
int *tmp_data = intvec->m_data;
// tmp_data = new int[10];
tmp_data[0] = 100;
tmp_data[1] = 200;
intvec->m_data[9] = 10;
// intvec->m_data = nullptr;
}

Intvec getIntPoint() {
Intvec intvec(10);
return intvec;
// const Intvec *intvec = new Intvec();
// intvec->m_data[0] = 1;
// return *intvec;
}

void modify_left(Intvec &&intvec) {
{
Intvec intvec_10(10);
std::swap(intvec.m_data, intvec_10.m_data);
}
cout << "\n ---end modify_left--\n";
}

void modify_left_string(std::string &&msg) {
cout << " ---end modify_left_string--" << msg.data();
}

class ReferenceIntvec {
private:
Intvec &intvec;
public:
void setIntvec(Intvec &intvec) {
cout << "\n ---ReferenceIntvec setIntvec Start--";
ReferenceIntvec::intvec = intvec;
cout << " ---ReferenceIntvec End--\n";
}

ReferenceIntvec(Intvec &intvec) : intvec(intvec) {
    cout << "\n ---ReferenceIntvec default Start--";

// ReferenceIntvec::intvec = intvec;
cout << " ---ReferenceIntvec default End--\n";
}

virtual ~ReferenceIntvec() {
    cout << " --- ~ReferenceIntvec--\n";
}

int getSize() {
    cout << "getSize " << &intvec << "  data ptr " << intvec.m_data;
    printf("  %p %p", &intvec, intvec.m_data);
    return intvec.m_size;
}

};

ReferenceIntvec *test_referenceIntvec(Intvec &intvec) {
cout << "\n ---test_referenceIntvec Start--";
ReferenceIntvec *referenceIntvec = new ReferenceIntvec(intvec);

// referenceIntvec.setIntvec(intvec);

cout << referenceIntvec->getSize() << " ---test_referenceIntvec End--\n";
return referenceIntvec;

}

void modify_normal(Intvec intvec) {
}

void modify_unique_copy(std::unique_ptr<Intvec> intvec) {

}

void modify_unique_reference(std::unique_ptr<Intvec> &intvec) {

}

std::unique_ptr<Intvec> return_modify_unique_copy() {
std::unique_ptr<Intvec> intvec_temp(new Intvec(10));
return intvec_temp;
}

void f(Intvec *p) {
p->m_size = 10; // (p.operator->())->m_size = 10
}

/**

  • 绑定env并判断入参列表是否存在null,为null则直接return
    */

define ATTACH_JNI_ENV_AND_RETURN_WHEN_CHECK_NP(tag, sum, ...)\

    bool needsDetach = false;\
    if(IsNullPoint(sum,__VA_ARGS__)){\
        printf("%s GetJniEnvSafe null point \n",tag);\
    }\

bool IsNullPoint(int sum, ...) {
va_list point;
va_start(point, sum);
for (int i = 0; i < sum; i++) {
void *result = va_arg(point, void * );
if (result == nullptr) {
va_end(point);
return true;
}
}
va_end(point);
return false;
}

void getIntResult(int **result) {
printf("after %p", result);
int temp = new int[3];
(
result) = temp;
temp[0] = 110;
}

struct structA {
int *a;
int *b;
//
// ~structA() {
// delete[] a;
// }
};

void getIntResult2(structA &structA1) {
structA1.a = new int[10];
// structA1.b = new int[10];

structA1.a[0] = 991;

// structA1.b[0] = 903;
}

std::thread::id main_thread_id = std::this_thread::get_id();

void is_main_thread() {
__thread_id id = std::this_thread::get_id();
if (main_thread_id == id)
std::cout << "This is the main thread.\n";
else
std::cout << "This is not the main thread.\n";
}

struct ColorStop {
float offset;
std::string color;

ColorStop() {
    printf("ColorStop() %p \n", this);
}

ColorStop(float offset, const std::string &color) : offset(offset), color(color) {
    printf("ColorStop(float) %p \n", this);
}

~ColorStop() {
    printf("~ColorStop destory %p \n", this);
}

friend ostream &operator<<(ostream &os, const ColorStop &stop) {
    os << "offset: " << stop.offset << " color: " << stop.color;
    return os;
}

};

class Gradient {

public:

float start[3];
std::vector<ColorStop> colorStops;

};

void pointer_func(const int *p, std::size_t size) {
std::cout << "data = ";
for (std::size_t i = 0; i < size; ++i)
std::cout << p[i] << ' ';
std::cout << '\n';
}

int func_vector() {
// input array
void *src = new float[5]{1.2f, 2.3f, 3.0f, 4.0f, 5.1f};
// int src[] = {1, 2, 3, 4, 5};
// int n = sizeof(src) / sizeof(src[0]);

auto *src_float = (float *) src;
std::vector<float> dest(src_float, src_float + 5);


for (float i: dest) {
    std::cout << i << " ";
}

std::cout << " \n";

Gradient gradientB;
{
    Gradient gradientA;
    ColorStop colorStop(2.0f, "abc");
    gradientA.start[0] = 99;
    gradientA.colorStops.push_back(colorStop);
    gradientB = gradientA;
}

std::cout << gradientB.colorStops.data()[0] << " \n";


return 0;

}

void test_cmp_str() {
modify_left(Intvec(100));//rValue
modify_left_string("adga12345中文呢也可以?么12345asdbsrg");//rValue

std::string string_equ("123456  ");
char *chars_equ = "123456  ";
printf("\n before chars_equ:%d,%s, string_equ:%d,%s, \n", strlen(chars_equ), chars_equ,
       string_equ.size(), string_equ.data());

int length = strlen(chars_equ);
char *mSystemFontLocation = new char[length + 1];
strcpy(mSystemFontLocation, chars_equ);
mSystemFontLocation[4] = '\0';
mSystemFontLocation[9] = '1';
printf("\n before mSystemFontLocation:%d,%s \n", strlen(mSystemFontLocation), mSystemFontLocation);

}

void swap_string() {
// Intvec intArray[10];
// intArray[0].m_size;
// void *void_ptr = static_cast< void *>(((&intArray[1])));

cout << "\n ---test1--\n";
{
    structA structA1;
    getIntResult2(structA1);

    if (structA1.a) {
        printf("structA1 a %d", structA1.a[0]);
    }

    if (structA1.b == nullptr) {
        printf("structA1 b  %p", structA1.b);
    }

    int *result = nullptr;
    printf("before %p", &result);
    getIntResult(&result);
    cout << "getIntResult  " << result[0] << endl;

// std::unique_ptr<Intvec> ptr1;
// ptr1 = return_modify_unique_copy();
}
cout << "\n ---test2--\n";
{
test_virtual();
}

{
    test_cmp_str();
}

{
    Intvec *intvec_temp = new Intvec(6);
    void *intvec_temp_1 = intvec_temp;
    delete intvec_temp;
    intvec_temp = nullptr;

    char *intvec_temp_2 = reinterpret_cast<char *>(intvec_temp_1);
    printf("intvec_temp  %p %p %p ,  %d", intvec_temp, intvec_temp_1, intvec_temp_2,
           intvec_temp_2);
}


cout << "\n ---end--\n";
if (true) {
    return;
}


cout << "\n ---test3--\n";
{
    test_default_copy();
}
cout << "\n ---test4--\n";
{

    cout << TEXTURE_EXTERNAL_SHADER_PS << endl;
    char *str_ = new char[100]{"12345678901234567890123456789012345678901234567890123456789012345678901234567890"};
    std::string a(str_);

// delete[] str_;
str_[0] = '0';
str_[1] = '0';
printf("modify a %s %s", a.data(), "~~~");
printf("modify str %s", str_);

    a = "abcde";
    if (a == "abcde") {
        cout << " == abcde \n";
    }

    test_template();
}

cout << "\n ---test5--\n";
{
    string *a = nullptr;
    string *b = nullptr;
    string *c = nullptr;

    ATTACH_JNI_ENV_AND_RETURN_WHEN_CHECK_NP("test5", 3, a, b, c);
}

Intvec *Intvec_100;
Intvec *Intvec_101;

cout << "\n ---test6  unique_ptr release--\n";
{
    Intvec_100 = new Intvec();
    std::unique_ptr<Intvec> temp(Intvec_100);
    temp->m_size = 100;
    temp->m_data[0] = 999;
    Intvec_101 = temp.release();
}
cout << "\n ---test6_1--\n";

// cout << Intvec_100->m_data[0] << "\n "; //直接闪退
cout << Intvec_101->m_data[0] << "\n "; //直接闪退

cout << "\n ---test7  move constructor map 1 重写move operator=  2不要从Map中取对象存在   增加、删除、使用(直接用)\n";
{

    int obja = 10;
    int *a = &obja;
    int *b = new int[10];

// delete[] a;
delete[] b;

    std::map<std::string, Intvec> IntvecMap;
    Intvec temp1(100);
    //给到std::map 先走默认构造Intvec,然后走move 等号&&操作符,更新值。所以要自行实现。


    IntvecMap["abc"] = std::move(temp1);


    auto result = IntvecMap.find("abc");
    if (result != IntvecMap.end()) {
        cout << "\nIntvecMap  find  " << result->first << "\n";
    } else {
        cout << "\nIntvecMap  not find  " << "\n";
    }

// Intvec temp2 = IntvecMap["abc"]; 不要这样用!!!!因为会走copy!!最好是用如下方案.直接使用
cout << "\n m_size: " << IntvecMap["abc"].m_size << "\n";

    // erase all odd numbers from c
    for (auto it = IntvecMap.begin(); it != IntvecMap.end();) {
        Intvec temp = std::move(it->second);
        it = IntvecMap.erase(it);
        cout << "erase" << temp.m_size << " end \n";

    }

    cout << "\n erase end\n";


    //创建Intvec_1直接走move构造函数

// Intvec Intvec_1 = std::move(temp1);
}

cout << "\n ---test8--  default copy  使用引用走默认的copy很容易出问题的\n";
{
    structA a;
    structA b;
    a.a = new int[3];
    a.b = new int[3];
    a.a[0] = 991;
    a.b[0] = 119;


    cout << a.a << "_" << a.b << endl;

    cout << b.a << "_" << b.b << endl;

    b = a;

    cout << b.a << "_" << b.b << endl;

}

cout << "\n ---test9--  return unique_ptr\n";
{
    std::unique_ptr<Intvec> ptr1;
    ptr1 = return_modify_unique_copy();

    cout << "\n" << ptr1->m_size << "\n";

// ptr1.release(); 人为泄漏
}

cout << "\n ---test10--  thread\n";
{
    is_main_thread();
    std::thread foo;
    std::thread bar(is_main_thread);
    std::cout << "foo: " << foo.joinable() << '\n';
    std::cout << "foo: " << bar.joinable() << '\n';
    bar.join();
}


cout << "\n ---end--\n";

cout << "\n ---test11--  return vector\n";
{
    func_vector();
}


if (true) {
    return;
}


cout << "\n ---swap_string--\n";
Intvec aa(10);
Intvec intvec1(getIntPoint());
cout << "\n ---swap_string1--\n";
intvec1 = getIntPoint();
cout << "\n ---swap_string2--\n";
modify_normal(intvec1); //作为函数入参是走的 构造函数。作为出参走等号赋值时走的符号重载
string a_str = "abc";
string b_str = "def";
a_str = std::move(b_str); //string重载了 移动赋值操作符 operator=(string&&),内部有swap操作。最终 b_str的内容为null

// a_str = b_str; //重载的是 复制赋值操作符 operator=(const string&)

cout << "\n ---swap_string end--\n" << a_str << b_str.data();

modify_left(getIntPoint());//rValue
modify_left(Intvec(100));//rValue


Intvec intvec = getIntPoint();

// modify_left(intvec);//lValue
// modify_left(static_cast<Intvec&&>(intvec));//lValue -> rValue
modify_left(std::move(intvec));//lValue -> rValue

std::unique_ptr<Intvec> up_intvec_1(new Intvec(10));

std::unique_ptr<Intvec> up_intvec_2(std::move(up_intvec_1));

// std::unique_ptr<Intvec> up_intvec_3(up_intvec_1);
std::auto_ptr<Intvec> auto_ptr1;
auto_ptr1 = auto_ptr1;
up_intvec_2 = move(up_intvec_1);

modify_unique_copy(std::move(up_intvec_2));
modify_unique_reference(up_intvec_2);
cout << "\n ---start--\n";

// Intvec intvec = getIntPoint();
// modify_left(intvec);
Intvec intvec2;
intvec2 = intvec;

int *a = new int[3];
a[0] = 10;
int *b = new int[3];
b[0] = 20;


cout << "swap_string " << a << "  " << b << endl;
//地址级别的交换
std::swap(a, b);
cout << "swap_string " << a << "  " << b << endl;
printf("%d %d \n", a[0], b[0]);

}

void test_reference() {
Intvec v1(20);
Intvec v2;
//
// cout << "assigning lvalue...\n";
// v2 = v1;
// cout << "ended assigning lvalue...\n";

cout << "assigning rvalue...\n";
v2 = Intvec(33);
cout << "ended assigning rvalue...\n";


int &&x = 10;
int aa = 10;
int &a = aa;
x = 100;
cout << "&&x " << &x << x << "\n";

}

template<class T>
void myswap(T &a, T &b) {
T tmp{std::move(a)}; // invokes move constructor
a = std::move(b); // invokes move assignment
b = std::move(tmp); // invokes move assignment
}

//值传递
void change1(int n) {
cout << "值传递--函数操作地址" << &n << endl; //显示的是拷贝的地址而不是源地址
n++;
}

//引用传递
void change2(int &n) {
cout << "引用传递--函数操作地址" << &n << endl;
n++;
}

//指针传递
void change3(int *n) {
cout << "指针传递--函数操作地址 " << n << endl;
*n = *n + 1;
}

int test_point() {
int n = 10;
cout << "实参的地址" << &n <<
endl;
change1(n);
cout << "after change1() n=" << n <<
endl;
change2(n);
cout << "after change2() n=" << n <<
endl;
change3(&n);
cout << "after change3() n=" << n <<
endl;
return true;
}

//值传递
void change1_array(int n) {
cout << "值传递--函数操作地址" << &n << endl; //显示的是拷贝的地址而不是源地址
n++;
}

//指针传递
void change3_array(int *n) {
cout << "指针传递--函数操作地址 " << n << endl;
*n = *n + 1;
}

int test_point_array() {
int *n = new int[3];
n[0] = 10;
n[1] = 20;

int valInt[4] = {0};
valInt[0] = 10;
valInt[1] = 20;

// cout << "实参的地址" << &n << endl;
// change1_array(n);
// cout << "after change1() n=" << n <<
// endl;
cout << "after change2() n=" << n <<
endl;
change3_array(n);
cout << "after change3() n=" << n <<
endl;
return true;
}

void swap(TestCase &testCase1, TestCase &testCase2) {

TestCase *case1 = &testCase1;
TestCase *case2 = &testCase2;
std::cout << "Hello, World! testCase1 " << case1->chars << case1 << &case1 << std::endl;
std::cout << "Hello, World!  testCase2 " << case2->chars << case2 << &case2 << std::endl;

printf("\n %p %p \n", &case1, case1);
printf("\n %p %p \n", &case2, case2);

TestCase *temp = case1;
case1 = case2;
case2 = temp;

std::cout << "Hello, World! testCase1 " << case1->chars << case1 << &case1 << std::endl;
std::cout << "Hello, World!  testCase2 " << case2->chars << case2 << &case2 << std::endl;

printf("\n %p %p \n", &case1, case1);
printf("\n %p %p \n", &case2, case2);

}

void split(std::string &str, char *separator, bool allow_empty_entries,
std::vector<std::string> &result) {
result.clear();

size_t start_pos = 0;
size_t end_pos;

while ((end_pos = str.find(separator, start_pos)) != std::string::npos) {
    if (allow_empty_entries || start_pos != end_pos)
        result.push_back(str.substr(start_pos, end_pos - start_pos));
    start_pos = end_pos + 1;
}

if (allow_empty_entries || start_pos != str.length())
    result.push_back(str.substr(start_pos));

}

void SplitStringHelper(std::string &str, std::unordered_set<std::string> &set) {
std::vector<std::string> substrings;

split(str, " ", false, substrings);

for (size_t i = 0; i < substrings.size(); ++i)
    set.insert(substrings[i]);

}

//引用是给编译器看的。可以看做是,经过编译器,又被转化为了指针。引用的好处是不用->箭头符号。并且引用不用主动delete释放。
void printString1(string &msg) {
printf("\n %s %p", msg.data(), &msg);
}

//会重新copy实例的。
void printString2(string msg) {
printf("\n %s %p", msg.data(), &msg);
}

void printString3(string *msg) {
printf("\n %s %p", msg->data(), msg);
}

void printString4(const char &msg) {
//前后地址一致
printf("\n %c %p", msg, &msg);
}

include <iostream> // std::cout

include <thread> // std::thread, std::this_thread::sleep_for

include <chrono> // std::chrono::seconds

void pause_thread(int n) {
std::this_thread::sleep_for(std::chrono::seconds(n));
std::cout << "pause of " << n << " seconds ended\n";
}

int main_fn() {
std::cout << "Spawning and detaching 3 threads...\n";
std::thread thread1(pause_thread, 2);
// std::thread(pause_thread, 2);
// std::thread(pause_thread, 3);
std::cout << "Done spawning threads.\n";

std::cout << "(the main thread will now pause for 5 seconds)\n";
// give the detached threads time to finish (but not guaranteed!):
pause_thread(1);
thread1.join();
return 0;

}

std::mutex mtx; // mutex for critical section

void print_block(int n, char c) {
// critical section (exclusive access to std::cout signaled by lifetime of lck):
std::unique_lock<std::mutex> lck(mtx);
// std::unique_lock<std::mutex> lck(mtx, std::defer_lock);
for (int i = 0; i < n; ++i) { std::cout << c; }
std::cout << '\n';
}

int main_fn2() {

std::atomic<bool> ready(false);
std::atomic_flag winner = ATOMIC_FLAG_INIT;
winner.test_and_set();

std::thread th1(print_block, 50, '*');
std::thread th2(print_block, 50, '$');
std::thread th3(print_block, 50, '0');
std::thread th4(print_block, 50, '1');

th1.join();
th2.join();
th3.join();
th4.join();

return 0;

}

include <mutex> // std::mutex, std::unique_lock

include <condition_variable> // std::condition_variable

std::condition_variable cv;
bool ready = false;

std::mutex prit;

void print_id(int id) {
// std::unique_lock<std::mutex> ptr_lck(prit, std::defer_lock);
// ptr_lck.lock();
// std::cout << "thread bef " << id << '\n';
// ptr_lck.unlock();

std::unique_lock<std::mutex> lck(mtx);
std::cout << "thread bef wait " << id << '\n';
while (!ready) cv.wait(lck);
// ...
std::cout << "thread aft wait" << id << '\n';

}

void go() {
std::unique_lock<std::mutex> lck(mtx);
ready = true;
cv.notify_all();
}

/**

  • 可以看到 thread bef wait 、 thread aft wait 串行打印的,没有发生不安全问题。

  • 进lck内,是线程安全的。走到wait后释放锁,等待notify,在竞争获取锁,还是线程安全的。
    */
    int main_fn3() {
    std::thread threads[10];
    // spawn 10 threads:
    for (int i = 0; i < 10; ++i)
    threads[i] = std::thread(print_id, i);

    pause_thread(1);
    // std::cout << "pause_thread(1) 10 threads ready to race...\n";
    go(); // go!

    for (auto &th : threads) th.join();

    return 0;
    }

int cargo = 0;

bool shipment_available() { return cargo != 0; }

void consume(int n) {
for (int i = 0; i < n; ++i) {
std::unique_lock<std::mutex> lck(mtx);
//while (!pred()) wait(lck);
cv.wait(lck, shipment_available);
// consume:
std::cout << cargo << '\n';
cargo = 0;
}
}

/**

  • 生产和消费的先后顺序不确定,先notify_one 后 wait,导致无法被唤醒。

*/
int main_fn4() {
std::thread consumer_thread(consume, 10);

// pause_thread(1);
// produce 10 items when needed:
for (int i = 0; i < 10; ++i) {
while (shipment_available()) std::this_thread::yield();
std::unique_lock<std::mutex> lck(mtx);
cargo = i + 1;
cv.notify_one();
}

consumer_thread.join();

return 0;

}

int value;

void read_value() {
std::cin >> value;
cv.notify_one();
}

int main_fn5() {
std::cout << "Please, enter an integer (I'll be printing dots): \n";
std::thread th(read_value);

std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);

while (cv.wait_for(lck, std::chrono::seconds(1)) == std::cv_status::timeout) {
    std::cout << '.' << std::endl;
}
std::cout << "You entered: " << value << '\n';

th.join();

return 0;

}

/**

  • 返回一个std::shared_ptr 也走move,走copy的情况下use_count加1
  • 返回一个std::unique_ptr 走的move
    */

std::shared_ptr<int> returnOneInt() {
std::shared_ptr<int> bar(new int(1099));
return bar;
}

int main_fn6() {
std::shared_ptr<int> foo;
std::shared_ptr<int> bar(new int(10));

foo = bar;                          // copy

std::cout << "use_count" << bar.use_count() << '\n';
std::cout << "use_count" << foo.use_count() << '\n';

bar = std::make_shared<int>(20);   // move

std::cout << "use_count" << bar.use_count() << '\n';
std::cout << "use_count" << foo.use_count() << '\n';
std::cout << "*foo: " << *foo << '\n';
std::cout << "*bar: " << *bar << '\n';

std::unique_ptr<int> unique(new int(30));
std::unique_ptr<int> unique2(new int(30));

foo = std::move(unique);            // move from unique_ptr

std::cout << "*foo: " << *foo << '\n';
std::cout << "*bar: " << *bar << '\n';

foo = returnOneInt();
std::cout << "use_count" << foo.use_count() << '\n';
std::cout << "*foo: " << *foo << '\n';

return 0;

}

//只有基类中被定义为 virtual 的方法,才会被虚函数表管理,最终表现出多态的特性~否则是没有的而Java默认都走多态
class AA {

private:
char *count = "data AA";
public:
AA() { cout << "\n ---构造AA-" << this << "-\n"; };

~AA() { cout << "\n ---~析构AA-" << this << "-\n"; };

AA(AA &&A) {
    printf("AA move constructor && ");
}

AA &operator=(AA &&other) {
    printf("AA move assignment operator && %p", this);
    return *this;
}

void fun1() {
    cout << "\n ---AA fun1--\n";
};

void fun2() {
    cout << "\n ---AA fun2--\n";
};

char *data() {
    return count;
};

};

AA createAA() {
AA a;
return a;
}

void processAA(char *data) {
printf("processAA %s", data);
}

//验证 智能指针已重载 == 运算符 nullptr
void testAA() {

{
    cout << "\n ---AA S--\n";
    processAA(createAA().data());
    cout << "\n ---AA E--\n";
}
cout << "\n ---AA EEE--\n";

shared_ptr<AA> adb_weak_shared;
std::weak_ptr<AA> adb_weak;

{
    auto adb = std::make_shared<AA>();
    adb_weak = adb;


    if (adb_weak.lock() == nullptr) {
        cout << "\n ---AA adb_weak_shared is null--\n";
    }

    if (adb_weak.lock() != nullptr) {
        cout << "\n ---AA adb_weak_shared not null--\n";
    }

    if (adb_weak.lock()) {
        cout << "\n ---AA adb_weak_shared not null--\n";
    }

    cout << "\n ---AA adb_weak_shared inner--\n";
}

adb_weak_shared = adb_weak.lock();

if (adb_weak.lock() == nullptr) {
    cout << "\n ---AA adb_weak_shared is null--\n";
}

if (adb_weak.lock() != nullptr) {
    cout << "\n ---AA adb_weak_shared not null--\n";
}

if (adb_weak.lock()) {
    cout << "\n ---AA adb_weak_shared not null--\n";
}

};

class BB : virtual public AA {
public:
~BB() {

}

void fun1() {
    cout << "\n ---BB--\n";
};

void fun2() {
    cout << "\n ---BB fun2--\n";
};

};

typedef void (*my_fun_lambda)(int);

class TestLambda {

public:

std::weak_ptr<AA> weak;

void testLambda() {
    cout << "\n ---testLambda--\n";

    std::function<void(int)> function1;
    {
        auto shared = std::shared_ptr<AA>(new AA());

// std::weak_ptr<AA> weak = shared;

        weak = shared;

        printf("input :%d before weak=%p %i \n", 0, &weak, weak.lock() != nullptr);

// auto lambda1 = [this](int in) {
// printf("input :%d run weak=%p %i \n", in, &weak, weak.lock() != nullptr);
// };

        auto lambda1 = [weak2 = weak](int in) {
            printf("input :%d  run weak=%p %i \n", in, &weak2, weak2.lock() != nullptr);
        };

        function1 = lambda1;

// cout << "\n ---testLambda {end}--\n";
function1(10);

    }
    function1(10);
}

};

typedef struct {
struct {
float r, g, b, a;
} rgba;
float components[4];

} GColorRGBA;

typedef int (*my_fun)();

/**

  • made mymap['b'] = AA(); 如果不手动处理&&,则存在构造两次走等号赋值copy的问题。
  • mymap['b']会创建一份。AA()也要创建一份。
    /
    void test_map() {
    std::map<char, AA> mymap;
    mymap['a'].fun1();
    cout << "map 自动创建对象--\n";
    mymap['b'] = AA();
    /
    *
    • ---构造AA-0x7ffeebcbb498-
    • ---构造AA-0x7ff009405a88-
    • ---~析构AA-0x7ffeebcbb498-
      */
      cout << "map 手动创建对象1--\n";
      mymap['b'].fun2();
      cout << "map 手动创建对象2--\n";
      }

int main() {

// GColorRGBA A = GColorRGBA({0, 0, 0, 0});
// GColorRGBA B = GColorRGBA({{0.0f / 255, 0.0f / 255, 0.0f / 255, 1.0f}});
{
main_fn6();
}

{
    //:bad_weak_ptr: bad_weak_ptr

// A *a = new A();
// a->getSharedPtr();
}
if (true) {
return 0;
}

test_map();
testAA();
TestLambda testLambda;
testLambda.testLambda();
if (true) {
    return 0;
}

// main_fn();
// main_fn2();
// main_fn3();
// main_fn4();
// main_fn5();
{
// my_fun fun_1 = main_fn;
void *aaaa = (void *) (main_fn);

    printf("main_fn : %p %p %p \n", main_fn, &main_fn, aaaa);

    AA *aa = new AA();
    BB *bb = new BB();

//
AA aa_Obj;
BB bb_Obj;
//
printf("test for virtual :%d %d ", sizeof(aa_Obj), sizeof(bb_Obj));
//
AA *aaa = (AA *) (bb);
aaa->fun1();
}

{
    cout << "\n ---0--\n";
    ReferenceIntvec *referenceIntvec;
    {
        cout << "\n ---00--\n";
        Intvec intvec(10);
        cout << "\n ---1--\n";
        referenceIntvec = test_referenceIntvec(intvec);
        cout << "\n ---2--\n";
    }
    cout << "\n ---3--\n";

    cout << referenceIntvec->getSize() << " 已经销毁了还能调用么--\n";
    cout << "\n --4---\n";

}
cout << "\n ---5--\n";
main_fn6();

test_point();

swap_string();


shared_ptr<A> sp1;
{
    cout << "\n ---test enable_shared_from_this--\n";
    shared_ptr<A> a(new A());
    sp1 = a->getSharedPtr();
    cout << sp1.use_count() << "-----";
}

sp1->f();
cout << sp1.use_count() << "-----";

{

    shared_ptr<C> sp_c;
    if (sp_c == nullptr) {
        cout << "\n -- sp_c is Empty-\n";
    } else {
        cout << "\n -- sp_c is not Empty-\n";
    }

    if (sp_c != nullptr) {
        cout << "\n -- sp_c1 is not Empty-\n";
    } else {
        cout << "\n -- sp_c1 is Empty-\n";
    }


    unique_ptr<C> uni_c;
    if (uni_c == nullptr) {
        cout << "\n -- uni_c is Empty-\n";
    } else {
        cout << "\n -- uni_c is not Empty-\n";
    }

    long abc = 0;
    auto abc_obj = (char *) abc;
    if (abc_obj == 0 || abc_obj == nullptr) {
        cout << "\n -- abc_obj is null-\n";
    } else {
        cout << "\n -- uni_c is not Empty-\n";
    }

    sp_c = std::make_shared<C>("abc");

// shared_ptr<C> sp_cc = sp_c;
{
cout << "\n -- reset before -\n";
sp_c.reset();
cout << "\n -- reset after -\n";
}
cout << "\n -- end -\n";
}

if (true) {
    return 0;
}

cout << "\n ------- \n";
Intvec intvec(10);
modify_intvec(&intvec);
printf("\nIntvec  %d  %d \n", intvec.m_data[0], intvec.m_data[1]);

test_reference();
printf("\n\n");

std::string poiS1;
{
    char *poi1 = "1234";
    std::string *poiS3 = new std::string("12345678");
    const char *poi = poiS3->c_str();
    poiS1 = std::string(poiS3->c_str());
    printf("\n 是个空么0:  %p %p %p\n", poi1, poi, poiS1.data());
    delete poiS3;
    printf("\n 是个空么1:  %s %s \n", poi, poi1);
    printf("\n 是个空么3:  %s poi1:%s \n", poi, poi1);
}
printf("\n 是个空么2:  %s   \n", poiS1.data());

// char *poi = "1234";
// std::string poiS1(poi);
// std::string poiS2(poi);
// printf("\n %s,%s,%s\n", poiS2.data(), poiS1.data(), poi);
// delete[] poi;
// printf("\n %s,%s \n", poiS2.data(), poiS1.data());
//

std::string abc("1abc    defg    abc    defg234     ");
std::string *abcP = &abc;

abc = abc + "5697";

const char *temp = abc.data();
printf("\n %c,%c,%p,%p,%p  \n", temp[2], *(temp + 2), temp, abcP, &abc);
//b,b,0x7febd1402c10,0x7ffee7799740,0x7ffee7799740

//在栈中的指针自身的地址,指针内的内容也就是堆地址,堆地址中的内容。
printf("\n %p,%p,%c  \n", &temp, temp, *temp);
// 1 0x7febd1402c10

printString4((*temp));
// 1 0x7febd1402c10


printString1(abc);
printString2(abc);
printString3(&abc);

std::string *def = new string("2abc defg 123   ");
string(def->data());
printString1(*def);
printString3(def);

delete (def);

//如何看是否野指针
int *inttemp = new int[10];
printf("\n %p %s", def, def->data());

std::unordered_set<std::string> myset;
SplitStringHelper(abc, myset);


std::cout << "\n" << myset.size();
std::cout << " myset contains:";
for (const std::string &x: myset) std::cout << " " << x;
std::cout << std::endl;


char *string1 = "abc";
std::unordered_set<std::string>::const_iterator got = myset.find(string1);
if (got == myset.end())
    std::cout << "not found in myset";
else
    std::cout << *got << " is in myset";
std::cout << std::endl;

// auto *gl3TestCase = new GL3TestCase();
TestCase *testCase = new TestCase();
TestCase *testCase4 = new TestCase();
// TestCase *testCase = dynamic_cast<tcu::TestCase >(gl3TestCase);
testCase->setChars("000000");
testCase->resetGLContext();
testCase4->setChars("444444");
swap(
testCase, *testCase4);

std::cout << "Hello, World!  " << typeid(*testCase).name() << std::endl;

char *chars1 = "1234";
char *chars2 = "56789";


chars2 = &(*chars1);

TestCase testCase1;
TestCase testCase2;
testCase1.setChars("1111");
testCase2.setChars("222222");


std::cout << "Hello, World! testCase1 " << testCase1.chars << &testCase1 << std::endl;
std::cout << "Hello, World!  testCase2 " << testCase2.chars << &testCase2 << std::endl;

swap(testCase1, testCase2);

std::cout << "Hello, World! testCase1 " << testCase1.chars << &testCase1 << std::endl;
std::cout << "Hello, World!  testCase2 " << testCase2.chars << &testCase2 << std::endl;
std::cout << "Hello, World!  " << chars2 << &(*(&chars1)) << (&chars1) << std::endl;

return 0;

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容

  • 1.new 、 delete 、 malloc 、 free 关系 delete 会调用对象的析构函数 , 和 n...
    可不期诺Cappuccino阅读 875评论 0 0
  • 写在前面: 犹豫了一下,不知道该不该发这么多。毕竟题目虽全,但是其实很多人看了不到一半,估计就会默默的收藏保存,等...
    Yt_cc阅读 14,666评论 1 6
  • C 语言内存管理指对系统内存的分配、创建、使用这一系列操作。 在内存管理中,由于是操作系统内存,使用不当会造成毕竟...
    yiyiyuan阅读 500评论 0 0
  • 数据格式详解 输入输出函数详解 字符串处理函数详解 内存函数详解 类详解 数据格式详解 2^8=256(同样是一个...
    我在东北玩泥巴_阅读 1,927评论 0 0
  • 不讲语言特性,只从工程角度出发,个人觉得C++标准委员会在C++11中对多线程库的引入是有史以来做得最人道的一件事...
    stidio阅读 13,303评论 0 11