TokeyRoad

Never underestimate your power to change yourself!


  • 首页

  • 标签

  • 分类

  • 归档

strcmp实现

发表于 2020-04-28 | 分类于 C++
字数统计: 257 | 阅读时长 ≈ 1

strcmp函数实现以及分析

strcmp函数原型

int strcmp(const char str1, const char str2);

str1 < str2 返回负值或-1

str1 == str2 返回0

str1 > str2 返回正值或1

实现原理

该函数实际上是对字符的ASCII码进行比较,实现方案:从前往后依次比较两个字符串的字符,如果不相等,就停止比较并返回结果,如果相等就继续,直到其中一个字符串遇到结束符’\0’为止。

Linux源码
1
2
3
4
5
6
7
8
9
10
int strcmp(const char* str1, const char* str2){
unsigned char c1, c2;
while(1){
c1 = *str1++;
c2 = *str2++;
if(c1 != c2) return (c1 < c2) ? -1 : 1;
if(!c1) break;
}
return 0;
}

自己用减法实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int strcmpNew2(const char* str1, const char* str2) {
int ret = 0;
while (!(ret = *(unsigned char*)str1 - *(unsigned char*)str2) && *str1) {
str1++;
str2++;
}
return ret;

//if (ret < 0){
// return -1;
//}
//else if (ret > 0){
// return 1;
//}
//return 0;
}
注意

这个函数体内没有判断参数为NULL时的情况,所以当传入NULL时程序会崩溃,中的strcmp也会崩溃

产生dump文件

发表于 2020-04-28 | 分类于 C++
字数统计: 243 | 阅读时长 ≈ 1

程序崩溃或发生异常时产生dump文件

核心API是:

1
2
CreateFile()
MinDumpWriteDump()

需要包含的头文件:

1
2
#include <DbgHelp.h>
#pragma comment(lib, "dbghelp.lib")

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdlib.h>
#include <string>

#include <DbgHelp.h>

#pragma comment(lib, "dbghelp.lib")



LONG WINAPI MyCustomUnhandledFilter(struct _EXCEPTION_POINTERS *lpExceptionInfo)
{
LONG iRet = EXCEPTION_EXECUTE_HANDLER;

TCHAR szDumpFileName[MAX_PATH] = { 0 };

SYSTEMTIME st = { 0 };
GetLocalTime(&st);
wsprintf(szDumpFileName, "%04d-%02d-%02d-%02d-%02d-%02d.dmp", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wMinute);

HANDLE hDumpFile = CreateFile(szDumpFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

if (hDumpFile == INVALID_HANDLE_VALUE)
{
DWORD dwErrorID = GetLastError();
printf("Failed to create dump file, error ID: %d\n", dwErrorID);

return iRet;
}

MINIDUMP_EXCEPTION_INFORMATION MindumpExceptionInfo = { 0 };
MindumpExceptionInfo.ThreadId = GetCurrentThreadId();
MindumpExceptionInfo.ExceptionPointers = lpExceptionInfo;
MindumpExceptionInfo.ClientPointers = FALSE;

BOOL bRet = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &MindumpExceptionInfo, NULL, NULL);

if (bRet)
{
printf("Succeeded to create dump file!\n");
}
else
{
printf("Failed to create dump file!\n");
}

CloseHandle(hDumpFile);

return iRet;
}

void crash(int a)
{
int i = 1;
int j = a;
//!!程序崩溃的地方
i /= j;
}

int main() {
SetUnhandledExceptionFilter(MyCustomUnhandledFilter);
char buf[10];
memset(buf, 0, sizeof(buf) * sizeof(char));
crash(0);
strcpy(buf, "123456789");

system("pause");
return 0;
}

vector resize与reserve区别

发表于 2020-04-27 | 分类于 C++
字数统计: 699 | 阅读时长 ≈ 2

std::vector的reserve和resize的区别

  1. reserve:分配空间,更改capacity但不改变size。
  2. resize:分配空间,更改capacity也改变size。

函数作用

reserve是容器预留空间,不会真正的去创建数组对象,在创建对象之前,不能引用容器内的元素,当加入新元素的时候使用push_bakc()/insert()函数。

resize是改变容器大小,并且创建对象,因此调用这个函数之后,就可以引用容器内的对象,加入新元素的时候可以使用operator[]操作符,或者引用迭代器来引用元素对象。

函数形式

reserve:一个参数,即需要预留的容器的空间;

resize:两个参数,第一个是容器新的大小,第二个是要加入容器中的新元素,如果这个参数被省略, 那么就调用元素对象的默认构造函数。

阅读全文 »

C++关键字(2)

发表于 2020-03-13 | 分类于 C++
字数统计: 603 | 阅读时长 ≈ 3
explicit

指定构造函数或转换函数为显示,即它不能用于隐式转换和复制初始化。

explicit说明符只能出现在类定义之内的构造函数或转换函数的声明说明符序列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct A{
A(int){}
A(int,int){}
operator int() const { return 0;}
};

struct B{
explicit B(int){}
explicit B(int,int){}
explicit operator int() const { return 0;}
};

void TestExpl(){
A a1 = 1; // A a1 = A(1);
// B b1 = 1; //error
A a2(2);
B b2(2); //OK
A a3 = {4,5}; // A a3 = A{4,5}; A{4,5};
// B b3 = {4,5};//error
int na1 = a1; //OK
//int na1 = b2; //error
int na2 = static_cast<int>(a1);
int nb2 = static_cast<int>(b2);
A a4 = (A)1;
B b4 = (B)1;
}
nullptr

C++11引入的,指代空指针。

阅读全文 »

深入学习C++关键字

发表于 2020-03-12 | 分类于 C++
字数统计: 795 | 阅读时长 ≈ 3
alignas&alignof
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

struct Foo {
int a;
char c;
float f;
};

struct Empty{};

struct alignas(64) Empty64 {};
//0会被忽略
struct alignas(0) BB {};

struct alignas(8) Double {
double d;
};

struct Obj {
char a;
int b;
};

//alignof
int s_obj = sizeof(Obj); //8
int a_obj = alignof(Obj); //4

void alignInfo() {
std::cout << "Alignment of" "\n"
"- char :" << alignof(char) << "\n" //1
"- pointer :" << alignof(int*) << "\n" //8 4
"- empty class :" << alignof(Empty) << "\n" //1
"- class Foo :" << alignof(Foo) << "\n" //4
"- alignas(64) Empty :" << alignof(Empty64) << "\n" //64
"- alignas(1) Double :" << alignof(Double) << "\n"; //8(WIN下编译报错)
}
and&&and_eq
1
2
3
4
5
6
7
8
9
#include <iso646.h>
void AND() {
//and 等价于 &
int a = 10;
int b = 20;
b and_eq a;
//等价于 b &= a;
//等价于 b = b & a;
}
asm

用于在C++代码中嵌入汇编语言,不常用

auto
  1. 对于变量,指定将要从其初始值设定项自动推断出要声明的变量的类型。

  2. 对于函数,指定将其从其return语句推导返回类型。

阅读全文 »
1…456…10
Tokey

Tokey

48 日志
9 分类
41 标签
  • C++8
  • Const1
  • Final1
  • HTTP2
  • Redis8
  • SDS1
  • STL4
  • TCP1
  • args1
  • atomic1
  • condition_variable1
  • construct1
  • foreach1
  • git2
  • go4
  • hexo1
  • json1
  • libcurl1
  • mutex1
  • operator1
  • override1
  • priority_queue1
  • shared_ptr1
  • stl1
  • unique_ptr1
  • vector1
  • 关键字2
  • 内存分配1
  • 列表对象1
  • 压缩列表2
  • 堆1
  • 字符串对象1
  • 指针和引用1
  • 敏捷开发1
  • 整数集合1
  • 栈1
  • 环境配置1
  • 缓存1
  • 设计模式1
  • 跳跃表1
  • 链表1
GitHub Google
Links
  • Hacker
本站已运行
© 2021 Tokey
博客全站共45.4k字
苏ICP备-20024031号
访问人数 总访问量 次
0%