C++判断char*的指向
char *a = "Peter";
char b[] = "Peter";
char *c = new char[];
strcpy_s(c, , "Peter");
这里a指向常量区
b指向栈区
c指向堆区
如果我们有这样一个函数
void show(char *temp)
{
//
//
//
}
我们如何判断根据过来的temp的将这些区分出来呢?
1.我们可以首先将指向常量区的a区分出来
因为它所指向的地方是不可以修改的
判断是否可以修改
a.使用函数IsBadReadPtr
函数原型如下
BOOL WINAPI IsBadWritePtr(
_In_ LPVOID lp,
_In_ UINT_PTR ucb
);
lp:第一个字节的内存块的指针。
ucb:指定的大小,单位为字节的内存块。如果此参数为零,则返回值为零。
MSDN上部分的解释如下
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366716(v=vs.85).aspx
Verifies that the calling process has write access to the specified range of memory.
Important This function is obsolete and should not be used. Despite its name, it does not guarantee that the pointer is valid or that the memory pointed to is safe to use. For more information, see Remarks on this page.
翻译(自己翻译的):
验证调用的进程是否可以写入指定范围的内存
主要的:这个函数是废弃的,不应该被使用,不管它的名字,它不保证这个指向内存中的指针是合法的和这段内存是可以安全使用的,对于更多的信息,可以查看这页的评论
示例:
bool isConst(void* pAddress, DWORD dwSize)
{
if (IsBadWritePtr(pAddress, dwSize))
return true;
return false;
} int main()
{
char *a = "Peter";
char b[] = "Peter";
char *c = new char[];
strcpy_s(c, , "Peter");
cout << isConst(a,strlen(a))<< endl;
cout << isConst(b, strlen(a)) << endl;
cout << isConst(c, strlen(a)) << endl; system("pause");
}
结果
b.使用VirtualQuery
函数原型如下
SIZE_T WINAPI VirtualQuery(
_In_opt_ LPCVOID lpAddress,
_Out_ PMEMORY_BASIC_INFORMATION lpBuffer,
_In_ SIZE_T dwLength
);
lpAddress:查询内存的地址。
lpBuffer:指向MEMORY_BASIC_INFORMATION结构的指针,用于接收内存信息。
dwLength:MEMORY_BASIC_INFORMATION结构的大小。
MSDN上部分的解释如下
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366902(v=vs.85).aspx
Retrieves information about a range of pages in the virtual address space of the calling process.
检索对于调用进程的虚拟内存中的页的信息
用于接收的内存信息的MEMORY_BASIC_INFORMATION结构体定义如下
typedef struct _MEMORY_BASIC_INFORMATION {
PVOID BaseAddress;
PVOID AllocationBase;
DWORD AllocationProtect;
SIZE_T RegionSize;
DWORD State;
DWORD Protect;
DWORD Type;
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
BaseAddress:保留区域的基地址
AllocationBase:分配的基地址
AllocationProtect:初次保留时所设置的保护属性
RegionSize:区域大小
State:状态(提交、保留或空闲)
Protect: 当前访问保护属性
Type:页面类型
详细请见MSDN
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366775(v=vs.85).aspx
示例
bool isConst(void* pAddress)
{
_MEMORY_BASIC_INFORMATION mi = { };
VirtualQuery(pAddress, &mi, sizeof(mi));
if (mi.Protect == PAGE_READONLY)
{
return true;
}
return false;
} int main()
{
char *a = "Peter";
char b[] = "Peter";
char *c = new char[];
strcpy_s(c, , "Peter");
cout << isConst(a)<< endl;
cout << isConst(b) << endl;
cout << isConst(c) << endl; system("pause");
}
结果
判断是否位于栈上
参考了http://www.cppblog.com/weiym/archive/2012/05/12/174634.html
我们可以在函数内建一个位于栈的对象,然后获得栈空间的初始地址,以及栈的最末尾的地址,就可以判断一个东西是不是为与栈上了
VirtualQuery中用于接收内存信息_MEMORY_BASIC_INFORMATION结构体中有如下成员
BaseAddress:保留区域的基地址
RegionSize:区域大小
代码示例
bool IsObjectOnStack(void* pObject)
{
int nStackValue(); MEMORY_BASIC_INFORMATION mi = { };
DWORD dwRet = VirtualQuery(&nStackValue, &mi, sizeof(mi));
if (dwRet > )
{
return pObject >= mi.BaseAddress
&& (DWORD)pObject < (DWORD)mi.BaseAddress + mi.RegionSize;
} return FALSE;
} int main()
{
char *a = "Peter";
char b[] = "Peter";
char *c = new char[];
strcpy_s(c, , "Peter");
cout << IsObjectOnStack(a) << endl;
cout << IsObjectOnStack(b) << endl;
cout << IsObjectOnStack(c) << endl; system("pause");
}
运行结果
解释:nStackValue是一个位于栈上的对象
我们针对它使用 VirtualQuery获得相关的内存信息mi
mi.BaseAddress是栈的初始地址
(DWORD)mi.BaseAddress + mi.RegionSize是栈的最末尾的地址
我们只要判断地址是不是在这二者之间,就可以判断是不是位于栈上了
C++判断char*的指向的更多相关文章
- Java 中判断char 是否为空格 和空
//判断是否char是否为空import java.util.*; public class test{ public static void main(String[] args){ String ...
- JAVA中判断char是否是中文的几种方法
1.方法一 char c = 'a'; if((c >= 0x4e00)&&(c <= 0x9fbb)) { System.out.println("是中文&qu ...
- 你好,C++(15)四两拨千斤——3.9 指向内存位置的指针
3.9 指向内存位置的指针 一天,两个变量在街上遇到了: “老兄,你家住哪儿啊?改天找你玩儿去.” “哦,我家在静态存储区的0x0049A024号,你家呢?” “我家在动态存储区的0x0022FF0 ...
- JS 判断数据类型的三种方法
说到数据类型,我们先理一下JavaScript中常见的几种数据类型: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Functi ...
- C语言中 指向函数的指针 简介
引子:在学习CPrimerPlus的第十四章的14.13节中,遇到了如下三行文字,是有关指向函数的指针的,把我搞晕了. char * fump(); //返回指向char的指针的函数 char (* ...
- 彻底搞定char/wchar_t/unicode
彻底搞定char/wchar_t!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! (2013-07-17 10:18:28) 转载▼ 从char/wchar_t到TCHAR(1) ...
- char类型输出地址
问题描述: 当输出char的地址时,发现输出的是一个字符: char ch = 'a'; cout<<&ch<<endl;//a @ 因为cout得到一个char类型的 ...
- NDK(14)Native的char*和Java的String相互转换
转自: http://www.cnblogs.com/canphp/archive/2012/11/13/2768937.html 首先确保C/C++源文件的字符编码是UTF-8与JAVA的class ...
- char指针
1.在C语言中,没有字符串类型,因此使用char指针表示字符串. 2.那么问题来了,使用char* 表示字符串,到哪里是结尾呢?因此需要一个特殊的字符作为哨兵,类似迭代器中的end(),这个哨兵就是' ...
随机推荐
- JavaScript总结(五)
详解DOM(文档对象模型(Docment Object Model)) ✍ DOM中定义了许多节点类型来表示节点的多个方面: 文档节点Document 最顶层的节点(跟节点),代表整个HTML文档, ...
- 基于Keras的imdb数据集电影评论情感二分类
IMDB数据集下载速度慢,可以在我的repo库中找到下载,下载后放到~/.keras/datasets/目录下,即可正常运行.)中找到下载,下载后放到~/.keras/datasets/目录下,即可正 ...
- [jmeter]linux下自动测试环境+持续集成ant+jmeter+Apache(httpd)环境搭建与使用
前言:考虑搭建一个接口性能自动化测试平台,时间又比较紧急,所以就现想到了用jenkins+ant+jmeter完成,考虑到在linux环境中本身就可以设置定时任务,暂时该自动化用例还不与项目集成关联, ...
- 1-[并发编程]-操作系统OS
1.为什么要有操作系统 现代的计算机系统主要是由一个或者多个处理器,主存,硬盘,键盘,鼠标,显示器,打印机,网络接口及其他输入输出设备组成. 一般而言,现代计算机系统是一个复杂的系统. 其一:如果每位 ...
- 【TJOI2015】线性代数
题面 题解 要求的是 \[ \sum_{i=1}^n\sum_{j=1}^na_ia_jb_{i,j} - \sum_{i=1}^na_ic_i \] 可以看出这是一个最大权闭合子图问题 代码 #in ...
- Spring3升级到Spring4时, 运行时出现找不到MappingJacksonHttpMessageConverter的情况
[org.springframework.web.context.ContextLoader]Context initialization failed org.springframework.bea ...
- lambda取两字符串的交集
取两个有规律字符串的交集,字符串的格式如下: “[3095139,9080109]” jar支持: fastjson 程序demo: import com.alibaba.fastjson.JSON; ...
- 【Python Learning第一篇】Linux命令学习及Vim命令的使用
学了两天,终于把基本命令学完了,掌握以后可以当半个程序员了♪(^∇^*) 此文是一篇备忘录或者查询笔记,如果哪位大佬看上了并且非常嫌弃的话,还请大佬不吝赐教,多多包涵 以下是我上课做的一些笔记,非常的 ...
- buglly热更新集成遇到的那些坑
首先说明使用热修复的意义,那就是你的apk包发出去了,万一发生了紧急异常需要修复,怎么办?这时候再发包上市场审核,也是有点慢了吧?而且错误发生在apk中,无法通过后台接口修复,这时候你就需要一个强大的 ...
- 第四节:Windows系统安装时BIOS设置及注意
BIOS系统 BIOS是英文"Basic Input Output System"的缩略词,直译过来后中文名称就是"基本输入输出系统".在IBM PC兼容系统上 ...