
c/c++
总结了一些c/C++的错误,知识点
优惠券已抵扣
余额抵扣
还需支付
¥9.90
¥99.00
购买须知?
本专栏为图文内容,最终完结不会低于15篇文章。
订阅专栏,享有专栏所有文章阅读权限。
本专栏为虚拟商品,基于网络商品和虚拟商品的性质和特征,专栏一经购买无正当理由不予退款,不支持升级,敬请谅解。
mzhan017
小张
展开
-
C++:abnormal terminate std::stoi,空串
在这里如果__endptr == __str,也就是没有内容的传作为参数,就会trigger这个exception/terminate。如果传递进来的是一个空数组,就会有问题。如果传递进来的是一个没有内容的string,也会导致这个问题。这个函数接受的参数是string对象。原创 2025-06-05 08:54:38 · 418 阅读 · 0 评论 -
C++: gcc _GLIBCXX_USE_C99_STDIO=1
看汇编还有一定的迷惑性,因为使用的是函数指针做参数来调用实际的C函数。从头文件看,是使用了C99版的stdio。原创 2025-06-05 08:46:24 · 140 阅读 · 0 评论 -
[C++] RAII, 老代码的问题,内存泄漏
比如最近关注公司产品的commit,发现解决memory leak的问题的commit真不少,时不时就会出来一个,不管是从现场或者是内部测试,很大一类就是因为没有相应的RAII机制。如果缺少RAII的设计存在,就需要开发者,每一个人,不管是有经验的老员工,还是没经验的新员工(当然当前部门已经很少招新人,至少可以说自从2017年以来就没进过几个新人,掐指一算也有八九年时间了,怪不得自从2016年以来收到的喜糖喜蛋就陡然变少了),时时提防错误分支的资源释放,如果遗漏,就会出现错误。原创 2025-06-03 16:54:17 · 20 阅读 · 0 评论 -
c/c++: 临界区划分不全的一个问题
摘要:文章分析了一个多线程竞争问题,原因是临界区划分不准确导致全局变量读取操作未被保护。当线程A读取资源时,线程B释放并修改了同一资源,导致A仍使用旧版本。原代码中读取操作在锁外,修复方案是将所有操作移至锁内,确保线程安全。核心在于正确规划临界区范围,避免资源竞争问题。(149字)原创 2025-05-27 07:51:25 · 314 阅读 · 0 评论 -
C++:RAII的不能顾名思义?
RAII(Resource Acquisition Is Initialization)的字面意思“资源获取是初始化”对于不了解背景的人来说较难理解。实际上,RAII的核心思想是在构造函数中获取资源,并在析构函数中释放资源。因此,更直观的表达可能是“Resource Acquisition in Constructor”(RAIC),这样可以直接联想到构造函数和析构函数的关系,减少理解上的绕路。RAII的设计模式在C++等编程语言中广泛用于资源管理,确保资源的自动释放,避免内存泄漏等问题。原创 2025-05-22 08:01:14 · 287 阅读 · 0 评论 -
c: 分号的歧义
文章探讨了编程语言中分号的使用问题,特别是在某些语言中,开发者习惯性地在每行代码后添加分号,这可能导致不必要的错误。作者指出,Python语言通过其语法设计,避免了这种问题,因为它不需要在每行代码后添加分号。文章提出了一个疑问:既然一行代码的结束本身就意味着语句的结束,为什么还需要用分号来明确表示结束?这反映了不同编程语言在语法设计上的差异和开发者习惯的影响。原创 2025-05-21 09:18:12 · 36 阅读 · 0 评论 -
gcc: attribute: packed
在C语言中,enum类型默认占用4个字节的内存空间。然而,通过使用__attribute__((packed))属性,可以强制编译器将enum类型压缩到最小可能的字节数。例如,在给定的代码中,enum类型abc在没有packed属性时占用4个字节,而加上packed属性后,它仅占用1个字节。这是因为packed属性告诉编译器尽可能紧凑地存储数据,减少内存占用。这一特性在处理内存敏感的应用时非常有用,但需要注意可能带来的对齐问题。原创 2025-05-19 14:50:36 · 112 阅读 · 0 评论 -
[晕事]今天做了件晕事76:switch分支没有给变量赋值?遗漏
在使用SonarQube进行代码检查时,发现一个潜在的错误:一个字符串指针变量在函数开始时被初始化为NULL,随后在一个switch语句中被赋值。然而,default分支未对该指针进行赋值,导致在后续使用该指针时可能引发错误。正确的做法应确保在default分支中也对指针进行赋值,或者在该分支中直接退出函数,以避免未定义行为的发生。这个例子展示了静态代码检查工具在捕捉常见编程错误中的重要性,提醒开发者在编写代码时需更加细致,确保所有路径都得到妥善处理。原创 2025-05-15 08:08:59 · 127 阅读 · 0 评论 -
Linux: lib: tcmalloc,gperftools
谷歌开发的开源类库TCMalloc是一个针对C和C++代码的定制化内存分配解决方案,旨在提供比标准库如glibc更快的多线程内存分配性能。TCMalloc通过优化malloc()和C++的new操作符,提高了内存分配的效率。此外,TCMalloc提供了详细的运行时内存分配统计信息,可以通过调用tcmalloc::MallocExtension::GetStats()获取。这一功能对于性能调优和内存管理非常有用。值得注意的是,Envoy代理软件也采用了TCMalloc,进一步证明了其在高效内存管理方面的优势。原创 2025-05-14 08:00:30 · 36 阅读 · 0 评论 -
英语单词:evaluate;evaluation
在C语言中,__verify_pcpu_ptr()函数用于验证传入的@ptr是否为合法的per-CPU指针,但在此过程中不会对指针进行求值(evaluation)。这意味着函数不会访问指针指向的内存地址或解引用指针,而仅检查指针的形式或合法性。这种设计是为了确保在实际使用per-CPU指针之前验证其合法性,同时避免提前访问可能导致的未定义行为或逻辑错误。例如,在验证指针后,实际的访问操作才会发生。这种机制既保证了安全性,又实现了泛化。原创 2025-05-13 09:38:20 · 160 阅读 · 0 评论 -
Linux: dev: cmake --help-policy CMP0115
今天遇到一个新的policy,有点奇怪,感觉老的行为更方便一点。算是cmake新版导致的一个行为改变。继续使用原来的行为。原创 2025-05-08 05:45:26 · 436 阅读 · 0 评论 -
[晕事]今天做了件晕事72,取模运算,多线程同步
解释,假如两个线程,同事获取到cnt_snap的值是49,然后两个线程先后做loc_cnt的加加,接下来的cnt_snap的值可能是51。在代码里,多线程可能调用到的一个代码片段里,定义了一个临时变量,临时存放多线程可访问的变量,然后做取模运算。所以,最好的方式,是按照增量来做判断,如果增量大于50做相应的逻辑。最近在看一个问题,应该是一个多线程同步的问题。原创 2025-04-23 09:10:28 · 125 阅读 · 0 评论 -
Linux:glibc: No such file or directory
最后调查是,这个程序是32位的程序,而当前机器没有安装相应版本的glibc,导致没有相应的动态解释器:/lib/ld-linux.so.2。最后,还是要说一下,这个execv的返回值,找不到文件,也没有打印出来到底是哪一个文件没有。这个让人比较苦恼,如果可以直接知道哪一个文件缺了,问题就好解决了。可以确保当前文件夹下面有这个文件。使用strace和ldd显示下面的结果。是不是感觉没有思路,怎么可能是这个情况呢?最近编译了一个程序,运行的时候出现错误,原创 2025-04-01 13:49:25 · 159 阅读 · 0 评论 -
glibc: GLIBC_2.28‘ not found
这个时候,应该怎么解决,因为当前运行的机器是低版本,而程序是高版本,解决方法,或者是将程序降级,或者将当前系统升级。在一个glibc的接口版本是GLIBC_2.25的lab上,运行不了在2.28上编译的程序。看哪一个方便,但是不能通过 临时复制libc.so 文件来解决,因为会遇到下面的错误。所以如果是简单解决就是按照低版本的应用程序,来适配当前系统的glibc版本。比如下面的程序运行提示。原创 2025-03-27 14:24:56 · 813 阅读 · 0 评论 -
C++:类型推导规则 unsigned short + 1
默认情况下,C/C++ 的整数常量 1 是 int 类型。所以 1 和 unsigned short 相加,得到一个int 类型的数据。整数提升规则:如果 unsigned short 能被表示为 int,那么它会提升为 int,否则提升为 unsigned int。unsigned short 的值在运算时会被 提升(promote) 到 int 或 unsigned int(取决于平台)。原创 2025-03-24 20:21:57 · 193 阅读 · 0 评论 -
gtest的一个局限,变参函数的stub/mock
GMock 不支持直接 mock 变参函数,但可以通过 封装 变参函数,让 mock 方法接受 可变参数列表(va_list) 或者 固定参数列表。✅ 如果可以改代码,用 方法 1:封装 va_list,然后用 ON_CALL() 和 MOCK_METHOD 进行 mock。✅ 如果不能改代码,用 方法 3:函数指针 直接替换 ipm_comml 实现。// Mock 返回值。// 使用 ON_CALL 设置默认行为。方法 1:封装变参函数。原创 2025-03-20 19:54:20 · 63 阅读 · 0 评论 -
C: warning: the result of the conversion is unspecified because 999 is outside the range of type A
像这种异常分支就google unit test检查不到了,是否可以从代码里把异常分支给删除?如果conversion的值超过某个enum类型的范围也会提示警告。现在这种gcc的检查也是非常的先进,原创 2025-03-18 09:08:43 · 40 阅读 · 0 评论 -
C++: C++ requires a type specifier for all declarations;gmock;MOCK_METHOD
也就是说,编译器期望看到一个明确的类型说明符(例如 int、float、class 等)来定义变量或函数的类型。缺少类型定义: 确保所有使用的类型都已定义。例如,IABC_IPINFO、ABC、DCE、BOOL 等类型是否已定义并包含了相关头文件。如果某些类型定义在特定命名空间中,确保你在使用它们时正确地引用了命名空间。在你的代码中,编译器无法识别某些类型或声明,因此它报错提示需要类型说明符。但是这里没有给出来,具体是哪一个类型没有定义,比较不好定位问题。头文件包含问题: 确保包含了所有必要的头文件。原创 2025-03-17 08:20:53 · 239 阅读 · 0 评论 -
[晕事]今天做了件晕事67,while条件判断
原因是先判断是否为空个字符。应该是先检查边界,再判断字符是否为空。原创 2025-03-07 09:28:58 · 71 阅读 · 0 评论 -
c++: error: jump to case label
在C++中,switch语句的case标签后面直接定义变量也是不允许的,因为C++遵循与C相同的规则,即case标签不创建新的作用域。因此,直接在case标签后定义变量会导致编译错误。通过在case标签后添加大括号 {},你创建了一个新的作用域,使得变量定义合法且安全。为了在C++中正确编译这段代码,你需要在case标签后创建一个新的作用域来定义变量。在C和C++中,case标签后不能直接定义变量,因为case标签不创建新的作用域。解决方法是在case标签后使用大括号 {} 创建一个新的作用域来定义变量。原创 2025-02-24 09:00:09 · 68 阅读 · 0 评论 -
C/C++: error: subscripted value is neither array nor pointer nor vector
根据错误提示,就非常容易理解,就是使用下标访问的值,不是一个数组也,不是一个指针,也不是一个向量。原创 2025-02-10 08:24:54 · 171 阅读 · 0 评论 -
C/C++: warning: unsigned conversion from ‘int‘ to ‘long unsigned int‘ changes from -4 to184467440737
这个警告的原因是,-Wsign-conversion 选项检测到了从 有符号整数(int,值 -4)转换为 无符号整数(unsigned long)时发生的值变化。表达式 ~0x3 产生 -4(在 32 位整数下),当与 unsigned long 类型的 __sz 进行按位与运算时,会触发 有符号到无符号的转换,导致溢出并出现不期望的值,如 18446744073709551612(即 -4 以 64 位无符号表示的值)。解释:size_t 类型更通用,能够在 32 位和 64 位系统上都正确工作。原创 2025-01-21 08:49:40 · 87 阅读 · 0 评论 -
C++: : error: expected type-specifier before ‘;‘ token
因为 new 的语法不正确。正确的语法应该用 new 为指针数组分配内存。gcc 8.5 build 没有问题,11.5 build 有问题。修改,其实new后面的两层括号是不需要;原创 2025-01-14 17:58:44 · 443 阅读 · 0 评论 -
glibc: __tz_convert死锁;localtime_r
如果malloc被篡改的话,可能导致__tz_convert 函数重新打印这个LOG,然后再次调用__tz_convert ,可能就出现死锁的情况。上面的mprotect的错误是因为第一个参数是内存地址但是,没有按照page对齐。今天碰到一个__tz_convert死锁的问题;通过strace看,是死在了futex。原创 2025-01-08 20:48:36 · 238 阅读 · 0 评论 -
C/C++:按照C的顺序,看汇编语言程序是乱序
在使用 gdb 的 disassemble(或 disass)命令时,如果你加了 /s 选项,gdb 会尝试显示对应的源代码,并将源代码和机器指令结合显示。而且需要注意分析的时候,虽然backtrace的行号是704,但是实际出问题的是705 行。gdb disass 的时候,将三四行的代码disass /s 到一行了,这个是什么原因?所以结果可能是编译器做了优化,而优化的时候,可能导致多行源代码逻辑混杂执行。但是从汇编看,log调用的函数赋值,和msg_ptr变量的赋值,有些交叉。合并多行源代码的逻辑。原创 2025-01-06 13:22:49 · 93 阅读 · 0 评论 -
[晕事]今天做了件晕事61,C++: 委托构造
这两个代码片段定义默认构造函数的方式在行为上是不同的,主要区别在于它们是否会正确调用目标构造函数来初始化对象。逻辑:ABC() 通过委托调用另一个构造函数 ABC(bool),并将 false 作为参数传递。效果:对象的初始化将由 ABC(bool) 构造函数完成。第一种方式(委托构造函数) 是正确的,符合现代 C++ 风格,能够正确初始化对象。逻辑:虽然看起来像是调用另一个构造函数,但实际上并没有影响当前对象的初始化状态。第二种方式(函数调用) 是错误的,无法初始化当前对象,可能导致未定义行为。原创 2025-01-06 10:34:58 · 181 阅读 · 0 评论 -
c++: error: use of deleted function ‘std::atomic<bool>::atomic(const std::atomic<bool>&)‘
看着英文的意思是,使用了被删除的函数“std::atomic::atomic(const std::atomic&)” ,看着是一个atomic的构造函数。要看源代码:libstdc++v3/include/std/atomic。为什么不让一开始copy过来呢。不够安全,还是不够符合规范。什么意思是不存在的函数吗?原创 2025-01-03 07:13:56 · 176 阅读 · 0 评论 -
C++: glibc: pthread: pthread_cond_destroy,程序hang一例
有的实现可能会导致,pthread_cond_destroy() 将 cond所引用的对象设置为无效值。在其被销毁后,仍然引用该对象的结果是未定义的。程序在退出的时候,调用到了pthread_cond_destroy,但是另一个线程还在pthread_cond_timedwait。代码里的注释,也在强调,应用程序需要在销毁convar的时候,确保没有waiter仍然被block。未定义的行为:指的是程序可能表现出任何行为,包括看似正常工作、崩溃或产生错误结果,这取决于具体的实现和环境。原创 2025-01-03 07:12:36 · 520 阅读 · 0 评论 -
c: warning: comparison is always false due to limited range of data type [-Wtype-limits]
这个是unsigned char类型的一个类型限制。做这个条件判断是没有意义的。原创 2024-12-11 08:40:39 · 95 阅读 · 0 评论 -
Linux: glibc: 频繁调用new/delete会不会导致内存的碎片
glibc的内存处理机制,是在释放的时候会自动将小块内存整合成大块内存,为接下来满足大块的需求的可能。而且程序也不是一直占着内存不释放(如果是一直不释放,要考虑是不是内存泄漏),这个和磁盘的碎片化还有些不一样,因为文件的存储时间长的多。而且每个程序对空间的申请量大多是有固定的模式,比如程序里的某个结构体的大小,固定就是10K,那就有了固定模式申请10K,释放10K,这个内存可以被重复利用。glibc 使用基于堆的内存分配方式,如果堆内存块被分割得过于零散,则可能导致某些内存不可用,即内存碎片。原创 2024-12-10 15:25:03 · 315 阅读 · 0 评论 -
[代码书写规范] 返回值必须检查
代码书写标准,必须检查返回值?原创 2024-12-05 07:51:50 · 54 阅读 · 0 评论 -
gdb: watch 实例
【代码】gdb: watch 实例。原创 2024-10-16 16:51:22 · 75 阅读 · 0 评论 -
glibc: USE_TCACHE
通过gdb可以看到redhat提供的是打开了这个选项。原创 2024-10-12 09:53:59 · 80 阅读 · 0 评论 -
c++: cannot find -lstdc++
【代码】c++: cannot find -lstdc++原创 2024-09-20 06:25:52 · 98 阅读 · 0 评论 -
c/c++: warning: ISO C90 forbids variable length array ‘a’
int a[n];a[3]=4;return 0;func(b);return 0;int a[n];^~~原创 2024-09-05 04:31:25 · 398 阅读 · 0 评论 -
程序员: 形参/实参
如果根据:https://mzhan017.blog.youkuaiyun.com/article/details/141693086;将函数看成函数,其实形参就是自变量,而函数输出是因变量。而自变量的实例,才是实参。原创 2024-09-02 15:36:46 · 91 阅读 · 0 评论 -
[glibc] free之后的内存什么时候还给操作系统?
从glibc的内部看,返回给系统的途径,要根据申请的方式来判断,比如根据实现,使用sbrk/brk申请的内存,要用sbrk/brk来返回给操作系统。如果系统内存不够用,可能会导致新的程序例的内存申请返回errno=12,申请不到内存。意思是说,当释放的内存(和前后可以整合的chunk之和)大小超过了这个值,就会走入整合的逻辑,在整合之后根据heap里的top空闲内存的大小(和M_TRIM_THRESHOLD作比较)来判断释放要做trim。举例:假如一个程序,申请的都是小内存,连续申请2G。原创 2023-12-08 21:10:06 · 658 阅读 · 0 评论 -
c/c++: function和procedure的区别
函数与过程的区别,一个有返回值,一个没有。原创 2024-08-30 04:23:36 · 298 阅读 · 0 评论 -
cppcheck: Consider using std::find_if algorithm instead of a raw loop. [useStlAlgorithm]
可以实现看到的逻辑简洁,代码精炼。原创 2024-08-24 13:49:56 · 114 阅读 · 0 评论 -
gcc: pragma GCC diagnostic push
通过下面的方式,可以让gcc在部分代码上,不做-Wconversion的校验,也就不上报Warning,警告。但是这种还是有些风险,最好是不用。可以放到宏定义函数的外围。原创 2024-08-20 10:52:29 · 201 阅读 · 0 评论