C++判断char*的指向

char *a = "Peter";
char b[] = "Peter";
char *c = new char[6];
strcpy_s(c, 6, "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[6];
strcpy_s(c, 6, "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 = { 0 };
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[6];
strcpy_s(c, 6, "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(0);

MEMORY_BASIC_INFORMATION mi = { 0 };
DWORD dwRet = VirtualQuery(&nStackValue, &mi, sizeof(mi));
if (dwRet > 0)
{
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[6];
strcpy_s(c, 6, "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*的指向,布布扣,bubuko.com

时间: 2024-10-25 17:13:52

C++判断char*的指向的相关文章

Java 中判断char 是否为空格 和空

//判断是否char是否为空import java.util.*; public class test{ public static void main(String[] args){ String str="abc abc"; char [] ch=str.toCharArray(); for(int i=0;i<ch.length;i++) { if(Character.isSpace(ch[i])) System.out.println("ok"); }

判断Char是否为数字

三种方法: 1.Char.IsDigit (aChar)              指示指定字符串中位于指定位置处的字符是否属于十进制数字类别 2.Char.IsNumber(aChar)        指示指定字符串中位于指定位置的字符是否属于数字类别 3.aChar>='0'&&aChar<='9'     判断aChar是否位于‘0’到‘9’之前  等同于第一种

判断标准输出是否指向一个终端

你有没有留意过下面这种场景: $  ls file1 file2 file3 file4 file5 $ ls | cat file1 file2 file3 file4 file5 单独执行 ls 时,它的输出是一行多个文件名,在它后面接个管道的话,它的输出就变成了一行一个文件名,这是为什么呢?这种表现的原理是:ls 程序自身可以判断出(通过 isatty() 库函数)它的标准输出是指向了一个终端,还是别的什么地方(管道或者普通文件).如果是前者,则按一行多个文件名输出,否则按一行一个输出.

JAVA中判断char是否是中文的几种方法

1.方法一 Java代码   char c = 'a'; if((c >= 0x4e00)&&(c <= 0x9fbb)) { System.out.println("是中文"); } 上面的方法很简单,但只能判断是否是中文,但不能判断是否是中文标点. 下面的方法很全面,中文字符标点都可以判断 2.方法二 Java代码   private static final boolean isChinese(char c) { Character.UnicodeBl

JavaSE8基础 instanceof 判断引用变量指向的是一个类的具体对象吗

os :windows7 x64    jdk:jdk-8u131-windows-x64    ide:Eclipse Oxygen Release (4.7.0)        code: package jizuiku.eleven302; public class Demo { public static void main(String[] args) { Demo d = new Demo(); Javaer j = new Javaer(); //引用d指向的是Javaer类的具体

char、signed char、unsigned char的区别

ANSI C 提供了3种字符类型,分别是char.signed char.unsigned char char相当于signed char或者unsigned char,但是这取决于编译器! 这三种字符类型都是按照1个字节存储的,可以保存256个不同的值. 不同的是取值范围signed char取值范围是 -128 到 127unsigned char 取值范围是 0 到 255 signed char的最高位为符号位,因此char能表示-128~127, unsigned char没有符号位,

(转载)你好,C++(15)四两拨千斤——3.9 指向内存位置的指针

你好,C++(15)四两拨千斤——3.9 指向内存位置的指针 3.9  指向内存位置的指针 一天,两个变量在街上遇到了: “老兄,你家住哪儿啊?改天找你玩儿去.” “哦,我家在静态存储区的0x0049A024号,你家呢?” “我家在动态存储区的0x0022FF0C号.有空来玩儿啊.” 在前面的章节中,我们学会了用int等数值数据类型表达各种数字数据,用char等字符数据类型表达文字数据,我们甚至还可以用结构体将多个基本数据类型组合形成新的数据类型,用以表达更加复杂的事物.除了这些现实世界中常见的

你好,C++(15)四两拨千斤——3.9 指向内存位置的指针

3.9  指向内存位置的指针 一天,两个变量在街上遇到了: “老兄,你家住哪儿啊?改天找你玩儿去.” “哦,我家在静态存储区的0x0049A024号,你家呢?” “我家在动态存储区的0x0022FF0C号.有空来玩儿啊.” 在前面的章节中,我们学会了用int等数值数据类型表达各种数字数据,用char等字符数据类型表达文字数据,我们甚至还可以用结构体将多个基本数据类型组合形成新的数据类型,用以表达更加复杂的事物.除了这些现实世界中常见的数据之外,在程序设计当中,我们还有另外一种数据经常需要处理,那

从char/wchar_t到TCHAR .

原文:http://blog.csdn.net/phunxm/article/details/5082618 一.ANSI和UNICODE 1.为什么要使用UNICODE?  (1) 可以很容易地在不同语言之间进行数据交换. (2) 使你能够分配支持所有语言的单个二进制.exe文件或DLL文件. (3) 提高应用程序的运行效率. Windows 2000是使用UNICODE从头进行开发的,如果调用任何一个Windows函数并给它传递一个ANSI字符串,那么系统首先要将字符串转换成UNICODE,