Sunday, January 30, 2022

[c++] 动态内存

C++ 动态内存

C++ 程序中的内存分为两个部分:

栈:在函数内部声明的所有变量都将占用栈内存。

堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。

很多时候,您无法提前预知需要多少内存来存储某个定义变量中的特定信息,所需内存的大小需要在运行时才能确定。

在 C++ 中,您可以使用特殊的运算符为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址。这种运算符即 new 运算符。

如果您不需要动态分配内存,可以使用 delete 运算符,删除之前由 new 运算符分配的内存

new 和 delete 运算符

下面是使用 new 运算符来为任意的数据类型动态分配内存的通用语法:

==============================================

new data-type;

==============================================

在这里,data-type 可以是包括数组在内的任意内置的数据类型,也可以是包括类或结构在内的用户自定义的任何数据类型。让我们先来看下内置的数据类型。例如,我们可以定义一个指向 double 类型的指针,然后请求内存,该内存在执行时被分配。我们可以按照下面的语句使用 new 运算符来完成这点:

==============================================

double* pvalue  = NULL; // 初始化为 null 的指针 

pvalue  = new double;   // 为变量请求内存

==============================================

如果自由存储区已被用完,可能无法成功分配内存。所以建议检查 new 运算符是否返回 NULL 指针,并采取以下适当的操作:

==============================================

double* pvalue  = NULL;

if( !(pvalue  = new double ))

{

   cout << "Error: out of memory." <<endl;

   exit(1);

==============================================

malloc() 函数在 C 语言中就出现了,在 C++ 中仍然存在,但建议尽量不要使用 malloc() 函数。new 与 malloc() 函数相比,其主要的优点是,new 不只是分配了内存,它还创建了对象。


在任何时候,当您觉得某个已经动态分配内存的变量不再需要使用时,您可以使用 delete 操作符释放它所占用的内存,如下所示:

==============================================

delete pvalue;        // 释放 pvalue 所指向的内存

==============================================

下面的实例中使用了上面的概念,演示了如何使用 new 和 delete 运算符:

==============================================

#include <iostream>

using namespace std;

int main ()

{

   double* pvalue  = NULL; // 初始化为 null 的指针

   pvalue  = new double;   // 为变量请求内存

   *pvalue = 29494.99;     // 在分配的地址存储值

   cout << "Value of pvalue : " << *pvalue << endl;

   delete pvalue;         // 释放内存

   return 0;

}

==============================================

当上面的代码被编译和执行时,它会产生下列结果:

==============================================

Value of pvalue : 29495

==============================================

数组的动态内存分配

假设我们要为一个字符数组(一个有 20 个字符的字符串)分配内存,我们可以使用上面实例中的语法来为数组动态地分配内存,如下所示:

char* pvalue  = NULL;   // 初始化为 null 的指针

pvalue  = new char[20]; // 为变量请求内存

要删除我们刚才创建的数组,语句如下:

delete [] pvalue;        // 删除 pvalue 所指向的数组

下面是 new 操作符的通用语法,可以为多维数组分配内存,如下所示:

==============================================

int ROW = 2;

int COL = 3;

double **pvalue  = new double* [ROW]; // 为行分配内存


// 为列分配内存

for(int i = 0; i < COL; i++) {

    pvalue[i] = new double[COL];

}

==============================================

释放多维数组内存:

==============================================

for(int i = 0; i < COL; i++) {

    delete[] pvalue[i];

}

delete [] pvalue;

==============================================

对象的动态内存分配

对象与简单的数据类型没有什么不同。例如,请看下面的代码,我们将使用一个对象数组来理清这一概念:

==============================================

#include <iostream>

using namespace std;


class Box

{

   public:

      Box() { 

         cout << "调用构造函数!" <<endl; 

      }

      ~Box() { 

         cout << "调用析构函数!" <<endl; 

      }

};

int main( )

{

   Box* myBoxArray = new Box[4];

   delete [] myBoxArray; // Delete array

   return 0;

}

==============================================

如果要为一个包含四个 Box 对象的数组分配内存,构造函数将被调用 4 次,同样地,当删除这些对象时,析构函数也将被调用相同的次数(4次)。


当上面的代码被编译和执行时,它会产生下列结果:

调用构造函数!

调用构造函数!

调用构造函数!

调用构造函数!

调用析构函数!

调用析构函数!

调用析构函数!

调用析构函数!


[c++] 文件和流

 iostream 标准库,它提供了 cin 和 cout 方法分别用于从标准输入读取流和向标准输出写入流。 

如何从文件读取流和向文件写入流。这就需要用到 C++ 中另一个标准库 fstream,它定义了三个新的数据类型:

数据类型描述
ofstream该数据类型表示输出文件流,用于创建文件并向文件写入信息。
ifstream该数据类型表示输入文件流,用于从文件读取信息。
fstream该数据类型通常表示文件流,且同时具有 ofstream 和 ifstream 两种功能,这意味着它可以创建文件,向文件写入信息,从文件读取信息。

要在 C++ 中进行文件处理,必须在 C++ 源代码文件中包含头文件 <iostream> 和 <fstream>。


reference

https://www.w3cschool.cn/cpp/cpp-files-streams.html

Saturday, January 29, 2022

[c++] 多態

https://www.w3cschool.cn/cpp/cpp-polymorphism.html

导致错误输出的原因是,调用函数 area() 被编译器设置为基类中的版本,这就是所谓的静态多态,或静态链接 - 函数调用在程序执行前就准备好了。有时候这也被称为早绑定,因为 area() 函数在程序编译期间就已经设置好了。

虚函数

虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。

我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。

纯虚函数

您可能想要在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。

我们可以把基类中的虚函数 area() 改写如下:

      // pure virtual function

      virtual int area() = 0;

Tuesday, January 25, 2022

[Package Image] Make Android userdata

1. 透過full pkg 升級

2. 升級完成後,等待首次開機完成

3. 進入MBOOT mode

4. 透過指令,將 emmc 資料寫入USB中(16G)

    mmc dd mmc2usb

5. 透過 imageusb 將整個 usb 轉成 bin 檔。

6. 由 BIN 中,將 userdata 抽離出來

    參考 packing_emmc_16G_writer.scr

    output/rel/img/00.bin 0x0 NON NON 0x0000000084210000 0x000000011b200000

    起始位置 0x84210000= 2216755200

    如果bs=512,因此skip要設定為4329600

    分割區大小 0x11b200000 = 4750049280 也就是4.7G

    如果bs=512,count要設定為9277440。

    又因為使用imageusb的關係,所以前面512為軟體資訊,因此,正確起始位置需要+1

    再透過linux dd command 

       dd if=fullemmc.bin of=userdata.img bs=512 count=9277440 skip=4329601

7. 檢查內容

mkdir newuserdata/

sudo mount -t ext4 userdata_speedup.img newuserdata/

進入查看

sudo umount newuserdata/ 

8. 將userdata.img壓縮後,放到T91打包的工具內。

     git clone ssh://url/t91_release_tool

/t91_release_tool/upstreamPKGPa/input/userdata_speedup.img.gz

/t91_release_tool/upstreamPKGSa/input/userdata_speedup.img.gz

9. 執行打包,build code

[Package image] index

Make Android userdata

EMMC First Boot: Speed up (EMMC seed)

First Boot: How to build and check first boot speed up emmc bin

First Boot: EMMC first boot speed up development record


Monday, January 24, 2022

[css] Picture Animation


Old 

=========================================================================

position: absolute;

overflow: hidden;

background-image:url("assets/bg_1.jpg");

background-image:url("assets/bg_2.jpg");

background-image:url("assets/bg_3.jpg");

background-image:url("assets/bg_afternoon_1.jpg");

     /*animation:fadeInOut 360s linear 2s infinite alternate;*/

      /*animation: example 5s linear 2s infinite alternate;*/

  animation-name: fadeInOut;

  animation-duration: 360s;

  animation-timing-function: ease-in-out; /*linear;*/

  animation-delay: 0s;

  animation-iteration-count: infinite;

  /*animation-direction: alternate;     */

  }


@keyframes fadeInOut {

0% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_1.jpg");}

11% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_2.jpg");}

22% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_3.jpg");}

33% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_afternoon_1.jpg");}

44% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_afternoon_2.jpg");}

55% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_afternoon_3.jpg");}

66% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_afternoon_4.jpg");}

77% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_afternoon_5.jpg");}

88% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_afternoon_6.jpg");}

100% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_1.jpg");}

} 

=========================================================================

New

=========================================================================

overflow: hidden;

background-image:url("assets/bg_1.jpg"),

url("assets/bg_2.jpg"),

url("assets/bg_3.jpg"),

url("assets/bg_afternoon_1.jpg"),

url("assets/bg_afternoon_2.jpg"),

url("assets/bg_afternoon_3.jpg"),

url("assets/bg_afternoon_4.jpg"),

url("assets/bg_afternoon_5.jpg"),

url("assets/bg_afternoon_6.jpg");

      animation: fadeInOut 360s ease-in-out 0s infinite; 

     /*animation:fadeInOut 360s linear 2s infinite alternate;*/

      /*animation: example 5s linear 2s infinite alternate;*/

  //animation-name: fadeInOut;

  //animation-duration: 360s;

  //animation-timing-function: ease-in-out; /*linear;*/

  //animation-delay: 0s;

  //animation-iteration-count: infinite;

  /*animation-direction: alternate;     */

  }


@keyframes fadeInOut {

0% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_1.jpg");}

11% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_2.jpg");}

22% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_3.jpg");}

33% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_afternoon_1.jpg");}

44% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_afternoon_2.jpg");}

55% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_afternoon_3.jpg");}

66% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_afternoon_4.jpg");}

77% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_afternoon_5.jpg");}

88% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_afternoon_6.jpg");}

100% {Transition: background-image 1s ease-in-out;

background-image:url("assets/bg_1.jpg");}

}

=========================================================================


However, MDN spec [2] *doesn't* indicate {{background-image}} is an *animatable* property. So it might be better to use CSS animation with another property e.g. {{opacity}}.
Also, from browser perspective, every operation setting the background-image will trigger a repaint which is expensive in rendering.


[1] https://developer.mozilla.org/en-US/docs/Web/CSS/background-image
[2] https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties

n8n index

 【n8n免費本地端部署】Windows版|程式安裝x指令大補帖  【一鍵安裝 n8n】圖文教學,獲得無限額度自動化工具&限時免費升級企業版功能