计算机

炮轰C语言

没想到吧?继上篇炮轰C++之后,我的工作语言不仅没有变高级,反而更底层了。最近在做的事情是把浏览器中某个重要进程的C++语言替换成C语言,以保证更高的安全性。在此做一些技术总结。

数据类型

char * & uint8_t*

char和uint_8没有区别,唯一的区别的uint_8的最高位是unsigned无符号的。

指针

指针最大的作用是用来传参数。包括函数的返回值。原先函数的返回值都可以放进参数列表里。

一般的情况就是取变量的地址,作为指针参数传进来。或者定义一个指针,将指针传进来。

特殊的是二级指针。当一个对象是指针作为参数传到函数里的时候,用指针接收是赋不上值的,需要用二级指针。

ClassA* obj= NULL;
xxx->Func(child_index, &obj);

void HDKey::Func(ClassA** obj) {
  *obj= xxx;
}

值得注意的是深拷贝和浅拷贝(老生常谈)。尤其是将类变量赋给一个临时变量,然后调用方法改变这个成员变量,类变量也会被改掉。这种问题其实很常见,需要注意。

字符串

char* 常用方法 strlen str_equals str_substring strtol str_startswith

内存分配

malloc & realloc & free

uint8_t* message_uint8 = (uint8_t*)malloc(message_uint8_len * sizeof(uint8_t));
message_uint8 = (uint8_t*)realloc(message_uint8, strlen(req->sign_info.message) * sizeof(uint8_t));
free(message_uint8);

内存copy用memcpy_s(dest,destSize,source,sourceSize); s表示安全

内存泄漏

如何防止内存泄漏?

  1. new malloc => delete free
  2. 成员变量指针 => 释放
  3. 二级指针 => delete [ ]
  4. base_array elems => 释放
  5. strlen => 判空
  6. 析构函数中,delete 类的成员变量
  7. 把一个变量赋给新值的时候,看下它之前有没有分配过内存。(这就是没有GC的坏处)
  8. 原则上 变量的释放顺序是:先创建的后释放,后创建的先释放(类似栈)
    HDKey* child_key = NULL;
    hd_key->DeriveChild(child_index, &child_key);
    //delete hd_key;
    hd_key = child_key;

VS调试

编译运行,注意看堆栈信息

添加watch(可以加表达式)

收获

写C语言最大的感受是离业务越来越远了,进入了抽象的代码世界。我们的工作就是和内存打交道,把一种数据类型转成另一种数据类型。即便是对于热爱计算机的人来说,这件事情也略显枯燥。

最大的收获可能就是自信吧。因为我之前是后端程序员,写过PHP、Java、Golang、js,但是总感觉自己不像是真正的程序员。现在可真是各种语言都了解了。算得上是真·全栈程序员了。

参考

HDWallet原理

最后更新于 2023年2月6日 by qlili

0 0 votes
Article Rating
guest

1 Comment
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
1
0
Would love your thoughts, please comment.x
()
x