C中的多态
C++这类面向对象语言的多态是建立在基类及派生类之间继承关系的基础上的。C不支持继承,所以我们得模拟结构体之间的继承。我们会定义和使用两个结构体来说明多态行为。Shape结构体表示基“类”,而Rectangle结构体表示从基类Shape派生...
C++这类面向对象语言的多态是建立在基类及派生类之间继承关系的基础上的。C不支持继承,所以我们得模拟结构体之间的继承。我们会定义和使用两个结构体来说明多态行为。Shape结构体表示基“类”,而Rectangle结构体表示从基类Shape派生...
不透明指针用来在C中实现数据封装。一种方法是在头文件中声明不包含任何实现细节的结构体,然后在实现文件中定义与数据结构的特定实现配合使用的函数。数据结构的用户可以看到声明和函数原型,但是实现会被隐藏(在.c/.obj文件中)。 只有使用数据结...
前面我们在函数指针和字符串中开发的sort函数用到了回调函数。因为排序示例没有用到多线程,有些程序员认为这不是回调函数。大家普遍认可的定义是如果一个线程的事件导致另一个线程的函数调用,就称为回调。将回调函数的指针传递给线程,而函数的某个事件...
两个或更多线程共享数据可能损坏数据。为了说明这个问题,我们会实现一个计算两个向量点积的多线程函数。多个线程会同时访问两个向量和一个和字段。当线程完成后,和字段会持有点积的值。 两个向量的点积通过把每个向量对应的元素相乘后得到的积再相加来计算...
如果两个指针引用同一内存地址,我们称一个指针是另一个指针的别名。别名并不罕见,不过可能会引发一些问题。下面的代码声明了两个指针,并把它们都指向同一地址: int num = 5; int* p1 = # int* p2 = ...
类型转换是一种基本操作,跟指针结合使用时很有用。转换指针对我们大有帮助,原因包括: 访问有特殊目的的地址; 分配一个地址来表示端口; 判断机器的字节序。 我们也会处理一个跟别名、强别名和restrict中的类型转换紧密相关的主题。 注意 机...
有很多静态分析工具可以检查指针的误用,此外,大部分编译器都有选项来监测本章提到的很多问题。比如说,GCC编译器的-Wall选项可以启用编译器警告。 下面说明本章的一些示例会产生什么样的警告,这里我们忘记在调用函数时写上括号了: if(get...
即便已经释放了内存,我们也不一定要用完指针或已释放的内存。有一个问题是:如果将同一块内存释放两次会发生什么。此外,一旦释放内存,我们可能就得保护留下的数据了。本节就来研究这几个问题。 重复释放 将同一块内存释放两次称为重复释放,指针重复释放...
在本节中,我们会研究解引操作和数组下标的误用,也会研究跟字符串、结构体和函数指针有关的问题。 很多安全问题聚焦的是缓冲区溢出的概念。覆写对象边界以外的内存就会导致缓冲区溢出,这块内存可能是本程序的地址空间,也可能是其他进程的,如果是程序地址...
在声明和初始化指针时可能会出现问题,更准确地说,指针初始化失败。在本节中,我们会研究出现这类问题的情况。 不恰当的指针声明 考虑如下声明: int* ptr1, ptr2; 声明本身没错,不过,可能跟我们的本意不同,它把ptr1声明为整数指...