指针

C++实现操作系统中进程调度的优先级调度算法和轮转时间片调度算法

这一生的挚爱 提交于 2019-12-27 12:01:15
操作系统中进程调度是处理及管理的核心内容。 阅读本文,需要有一定的C/C++、数据结构基础。 内容介绍 采用C++编写程序,选用 优先数调度算法 或 简单轮转法 对五个进程进行调度,每个进程处于运行(Run)、就绪(Ready)和完成(Finish)三种状态之一,并假定起始状态为 就绪 状态。 进程控制块结构 进程控制块的链结构 其中: Run——表是当前运行进程指针, Ready——就绪队列头指针 Tail——就绪队列尾指针 Finish——完成队列指针 算法说明 (1) 为了便于处理,程序中进程的运行时间以时间片为单位进行计算,各进程的优先数或轮转时间片数,以及进程需要运行的时间片数,其初始值均有用户给定。 (2) 优先数法 进程就绪队列按优先数大小从高到低排列,链首进程首先投入运行。进程每执行一次,进程需要的时间片数减1、该进程的优先数减3。这样,该进程如果在一个时间片中没有完成,其优先数降低一级。接着仍是用该进程降低一级后的优先数与就绪队列中链首进程的优先数进行比较,如果仍是该进程的优先数高或相同,便让该进程继续执行;否则,调度就绪队列的链首进程投入运行。原运行过的进程按其现行优先数大小插入就绪队列,且改变它们对应的进程状态,一直到所有进程都运行完各自的时间片数。 (3) 简单轮转法 进程就绪队列按各进程进入的先后顺序排列

常量指针与指针常量

瘦欲@ 提交于 2019-12-27 11:24:58
int * const p; const int * const p; int const * const p; 这样的话,一共有六种,如下: ①const int p; ②const int* p; ③int const* p; ④int * const p; ⑤const int * const p; ⑥int const * const p; 第一种是常量整数,没什么好说的。 后面五种是指针,有一个简便的办法记忆。 从右往左读,遇到p就替换成“p is a ”遇到*就替换成“point to”。 比如说②,读作:p is a point to int const. p是一个指向整型常量的指针。 ③读作:p is a point to const int. 意思跟②相同。 ④读作:p is a const point to int. p是一个常量指针,指向整型。 ⑤读作:p is a const point to int const. ⑥读作:p is a const point to const int. ⑤和⑥的意思相同,p都是常量指针,指向整型常量。 这种方法来源于《c primer plus》,这里也向c初学者推荐此书。 且注意:允许把非 const 对象的地址赋给指向 const 对象的指针,不允许把一个 const 对象的地址赋给一个普通的、非 const

进程内核栈、用户栈

扶醉桌前 提交于 2019-12-27 10:18:34
Linux 进程栈和线程栈的区别 http://www.cnblogs.com/luosongchao/p/3680312.html 总结: 线程栈的空间开辟在所属进程的堆区,线程与其所属的进程共享进程的用户空间,所以线程栈之间可以互访。线程栈的起始地址和大小存放在pthread_attr_t 中,栈的大小并不是用来判断栈是否越界,而是用来初始化避免栈溢出的缓冲区的大小(或者说安全间隙的大小) 进程内核栈、用户栈 1.进程的堆栈 内核在创建进程的时候,在创建task_struct的同事,会为进程创建相应的堆栈。每个进程会有两个栈,一个用户栈,存在于用户空间,一个内核栈,存 在于内核空间。当进程在用户空间运行时,cpu堆栈指针寄存器里面的内容是用户堆栈地址,使用用户栈;当进程在内核空间时,cpu堆栈指针寄存器里面的内 容是内核栈空间地址,使用内核栈。 2.进程用户栈和内核栈的切换 当进程因为中断或者系统调用而陷入内核态之行时,进程所使用的堆栈也要从用户栈转到内核栈。 进程陷入内核态后,先把用户态堆栈的地址保存在内核栈之中,然后设置堆栈指针寄存器的内容为内核栈的地址,这样就完成了用户栈向内核栈的转换;当进程从内 核态恢复到用户态之行时,在内核态之行的最后将保存在内核栈里面的用户栈的地址恢复到堆栈指针寄存器即可。这样就实现了内核栈和用户栈的互转。 那么

第4章 变量、作用域和内存---JS红宝书书摘系列笔记

房东的猫 提交于 2019-12-27 10:16:59
一、基本类型和引用类型 ECMAScipt变量可能分为两种数据类型:基本类型和引用类型。 基本类型:指简单的数据段;包括Undefined、Null、Boolean、Number、String;可以操作保存在变量中值(栈内存),所以称为按值访问;不能添加属性。 引用类型:可能由多个值构成的对象;包括Arry、Object等;js不允许直接操作对象的内存(堆内存)空间,所以成为按引用访问;可以动态得添加/改变/删除引用类型值的属性和方法。 1.复制 1 var a=5; 2 var b=a; 3 console.log(a);//5 4 console.log(b);//5 5 a=3; 6 console.log(a);//3 7 console.log(b);//5 8 var arrA=[1,2,3]; 9 var arrB=arrA; 10 console.log(arrA);//[1,2,3] 11 console.log(arrB);//[1,2,3] 12 arrA[0]='x'; 13 console.log(arrA);//['x',2,3] 14 console.log(arrB);//['x',2,3] 上述代码中a、b为基本数据类型,arrA、arrB为引用类型。可以看出首先定义并初始化了变量a为5,再定义变量b,此时打印出来a和b都是5;改变a的值为3

auto_ptr

柔情痞子 提交于 2019-12-27 07:43:38
auto_ptr指针介绍(智能指针)   auto_ptr指针介绍   auto_ptr是这样一种指针:它是“它所指向的对象”的拥有者。这种拥有具有唯一性,即一个对象只能有一个拥有者,严禁一物二主。当auto_ptr指针被摧毁时,它所指向的对象也将被隐式销毁,即使程序中有异常发生,auto_ptr所指向的对象也将被销毁。   1、设计动机:   在函数中通常要获得一些资源,执行完动作后,然后释放所获得的资源,当程序员忘记释放所申请的到的资源,或者由于异常发生而没有正常释放资源时,这就将产生一系列的内存泄漏问题。   因此,你可能将函数写成如下形式:   void fun()   {   try   {   T *ptr = new T;   ......   }catch(...)   {   delete ptr;   throw;   }   delete ptr;   }   这样使程序变得太过复杂。使用auto_ptr可以使上述程序简化为:   void fun()   {   auto_ptr<T> ptr(new T);   ......   }   不再需要delete,也不再需要catch了。与上面的程序相比,这个非常简单。   auto_ptr是一个模板类,适合于任何类型,其接口行为与普通指针相似,opeator *用来提取其所指向对象的值。operator-

智能指针auto_ptr详解

孤街醉人 提交于 2019-12-27 07:40:50
主要内容转自http://www.cppblog.com/SmartPtr/archive/2007/07/05/27549.html 1. 智能指针auto_ptr的引入 auto_ptr是C++标准库中的智能指针模板类,头文件<memory> auto_ptr的出现,主要是为了解决“有异常抛出时发生内存泄漏”的问题。如下的简单代码是这类问题的一个简单示例。 int* p = new int(100); try { doSomething(); cout << *p << endl; delete p; } catch(exception& e) { } 当doSomething();部分抛出异常,将导致指针p所指向的空间得不到释放而导致内存泄露。auto_ptr的引入解决了这类问题。 2. auto_ptr的源代码(未可读性进行了少许改动的源码) 1 namespace std 2 { 3 template<class T> 4 class auto_ptr 5 { 6 private: 7 T* ap; 8 public: 9 10 // constructor & destructor ----------------------------------- (1) 11 explicit auto_ptr (T* ptr = 0) throw() : ap(ptr){}

auto_ptr

情到浓时终转凉″ 提交于 2019-12-27 07:39:54
1、   int *pi = new int(1024);   delete pi; // 释放pi指向的int对象占用的内存空间   pi = 0; // 将pi设置为0,不指向任何东西,为Null   注意:删除0值的指针是安全的,但是没有任何意义。对于上面的情况,先释放内存,再置为Null。顺序不能颠倒,如果颠倒了,会导致内存泄漏。 2、在Stack上分配的内存,用完后,系统会自动释放,调用析构方法。在Heap上,通过new分配内存,必须使用delete,手动释放内存,如果忘记,会导致内存泄漏。如果重复释放内存,会破坏自由存储区,导致分配在上面的其他对象受到破坏。(Stack记录程序的执行过程,Heap存放数据) 3、为了解决上面的问题,使用auto_ptr 4、auto_ptr是一个模版类,对一个类型的指针进行封装,把delete操作放在析构方法中,由于析构方法总是被调用,就保证了内存不会泄露。 5、auto_ptr是一个模版类,为了让auto_ptr使用起来像一个指针,重载*与->操作符。 6、用a对象copy构造b对象的时候,要把a的指针设为0,为什么?   如果,不把a的指针设为0,a,b都会在析构方法中进行delete,导致重复释放。 7、把a对象copy赋值给b对象的时候,首先要把b对象的指针delete,然后把a的指针设为0,为什么?   b的指针指向了a的指针

auto_ptr

会有一股神秘感。 提交于 2019-12-27 07:38:46
C++的auto_ptr auto_ptr所做的事情,就是动态分配对象以及当对象不再需要时自动执行清理。 1 构造函数与析构函数 auto_ptr在构造时获取对某个对象的所有权(ownership),在析构时释放该对象。我们可以这样使用auto_ptr来提高代码安全性: int* p = new int(0); auto_ptr<int> ap(p); 从此我们不必关心应该何时释放p, 也不用担心发生异常会有内存泄漏。 这里我们有几点要注意: 1) 因为auto_ptr析构的时候肯定会删除他所拥有的那个对象,所有我们就要注意了,一个萝卜一个坑,两个auto_ptr不能同时拥有同一个对象。像这样: int* p = new int(0); auto_ptr<int> ap1(p); auto_ptr<int> ap2(p); 因为ap1与ap2都认为指针p是归它管的,在析构时都试图删除p, 两次删除同一个对象的行为在C++标准中是未定义的。所以我们必须防止这样使用auto_ptr. 2) 考虑下面这种用法: int* pa = new int[10]; auto_ptr<int> ap(pa); 因为auto_ptr的析构函数中删除指针用的是delete,而不是delete [],所以我们不应该用auto_ptr来管理一个数组指针。 3)

C++智能指针剖析(上)std::auto_ptr与boost::scoped_ptr

时光毁灭记忆、已成空白 提交于 2019-12-27 07:38:15
1. 引入 C++语言中的动态内存分配没有自动回收机制,动态开辟的空间需要用户自己来维护,在出函数作用域或者程序正常退出前必须释放掉。 即程序员每次 new 出来的内存都要手动 delete,否则会造成内存泄露, 有时我们已经非常谨慎了 , 然防不胜防: 流程太复杂,程序员忘记 delete; 异常导致程序过早退出,没有执行 delete的情况屡见不鲜。 1 void FunTest() 2 { 3 int *p = new int[10]; 4 FILE* pFile = fopen("1. txt", "w"); 5 if (pFile == NULL) 6 { 7 return; //如果pFile == NULL则p指向的空间得不到释放 8 } 9 // DoSomethint() ; 10 if (p != NULL) 11 { 12 delete[] p; 13 p = NULL; 14 } 15 } 16 void FunTest2() //异常导致程序提前退出 17 { 18 int *p = new int[10]; 19 try 20 { 21 DoSomething(); 22 } 23 catch(. . .) 24 { 25 return; 26 } 27 delete[] p; 28 }

内存管理之智能指针unique_ptr&weak_ptr

妖精的绣舞 提交于 2019-12-27 07:37:50
unique_ptr: 1.unique_ptr与shared_ptr不同,某个时刻只能有一个unique_ptr指向给定的对象,当unique_ptr被销毁时,其所指向的对象也被销毁,和shared_ptr一样,unique_ptr默认使用delete释放指向的对象 2.unique_ptr初始化 1.不初始化,返回一个内容为nullptr的unique_ptr unique_ptr<类型> 指针名; 2.使用内置类型指针直接初始化 unique_ptr<类型> 指针名(内置类型指针p); 这里的p --> 类型* p = new 类型() unique_ptr<类型> 指针名(new<类型>())//unique_ptr与new结合使用 3.unique_ptr独占指向的对象,不支持赋值和拷贝操作 例子: unique_ptr<string> p1(new string("hello,world")); // 正确,直接初始化 unique_ptr<string> p2(p1); // 错误,unique_ptr不支持拷贝操作 unique_ptr<string> p3; // 正确,返回一个内容为nullptr的unique_ptr p3 = p1; // 错误,unique_ptr不支持赋值操作 4.了解reset()和release()方法 虽然不能拷贝或者赋值