常量区的修改

本文介绍了一个C程序,该程序通过使用VirtualProtectEx和WriteProcessMemory函数来修改已存在于常量区的数据。这两个函数允许程序更改另一进程的内存保护,并向指定进程的内存区域写入数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <Windows.h>
#include <stdio.h>
int main()
{
	const char* a = "123456";
	const char* b = "123456";
	char* c = "654321";

	DWORD oldprot; 
	HANDLE hProcess = GetCurrentProcess(); 
	VirtualProtectEx(hProcess, (LPVOID)b, 7, PAGE_EXECUTE_READWRITE, &oldprot);
	WriteProcessMemory(hProcess, (LPVOID)b, (LPVOID)c, 7, NULL);

	printf("%s \n", a);
}


以上程序输出  654321


“123456”是储存在常量区的,也就是说是在编译的时候就确定的,a、b、c只是一个指向常量区的指针。

由于编译器的优化,此时 a = b

VirtualProtectEx : Changes the protection on a region of committed pages in the virtual address space of a specified process.

WriteProcessMemory:Writes data to an area of memory in a specified process. The entire area to be written to must be accessible or the operation fails.

<think>好的,我需要帮助用户理解C语言中字符常量区和全局别及作用。首先,我得回忆一下相关的知识点,并结合用户提供的引用内容来组织答案。 用户提到了引用[1]中的例子,其中比较了字符数组和字符指针的别。字符数组str1存放在栈,而字符指针str2指向的字符串在字符常量区,也就是全局。这应该是一个关键点,说明字符常量区属于全局的一部分,但可能还有其他域。 引用[3]中的代码示例也展示了类似的情况,函数返回指向字符常量的指针可以正常工作,而返回局部字符数组则导致问题,因为栈的内存在函数结束后被释放。这说明字符常量区的数据在程序生命周期内有效,而栈的数据是临时的。 接下来,全局的定义可能包括静态存储,存放全局变量、静态变量和常量。而字符常量区是全局中的一部分,专门存放字符串常量。这里需要明确分全局的其他部分,比如未初始化的全局变量可能在BSS段,而初始化的在数据段,但用户的问题可能更关注字符常量区和其他全局存储位置的别。 引用[5]提到全局变量在所有函数之前定义,可以在多个函数中访问,这也属于全局的作用。而字符常量区的数据是只读的,不可修改,如用户示例中的str2指向的字符串,如果尝试修改会导致错误。 需要总结两者的别:存储内容、生命周期、访问权限。字符常量区存放字符串常量,只读,生命周期到程序结束;全局可能包括其他全局变量,如初始化和未初始化的,可能可读写,但具体要看类型。例如,全局变量如果是非const的,可以修改,而字符常量区的数据不可修改。 同时,用户的问题可能混淆了全局和字符常量区的概念,需要指出字符常量区是全局的一部分,或者是否属于全局。根据引用中的描述,字符常量区属于全局,但可能有更细的划分,比如代码、数据、BSS等,而字符常量区可能在数据的只读部分。 需要确保回答结构清晰,分点说明别和作用,并引用用户提供的例子来支持说明。可能还需要提到内存布局的不同域,如栈、堆、全局(数据段、BSS段)、代码段等,其中字符常量区位于代码段或数据段的只读部分。 最后,生成相关问题,帮助用户进一步理解,比如如何正确使用字符常量区,或全局变量的作用域问题。</think>在C语言中,字符常量区和全局在内存管理中扮演不同角色。以下是两者的核心别与作用: --- ### 一、字符常量区 1. **存储内容** 专门存放**字符串常量**,例如`char *p = "abc"`中的`"abc"`。这些字符串是**只读**的,不可修改[^1]。 2. **生命周期** 从程序启动到结束始终存在,由系统自动管理。 3. **访问权限** 若尝试修改内容(如`p[0] = 'A'`),会导致未定义行为(通常程序崩溃)[^1][^3]。 4. **典型示例** ```c char *test1() { char *p = "abc"; // "abc"存放在字符常量区 return p; // 合法,常量区数据生命周期长 } ``` --- ### 二、全局(静态存储) 1. **存储内容** 包含**全局变量**、**静态变量**(`static`修饰)和**常量**(如字符串常量)。例如: ```c int global_var; // 未初始化全局变量(BSS段) static int static_var; // 静态变量 ``` 2. **生命周期** 与程序生命周期一致,初始化后的变量在程序启动时分配内存。 3. **访问权限** - 全局变量和静态变量可读写。 - 字符串常量仍为只读(属于字符常量区的子集)[^1][^5]。 4. **作用域** - 全局变量:整个程序可见。 - 静态变量:文件或函数内可见。 --- ### 三、核心别 | **特性** | 字符常量区 | 全局 | |----------------|--------------------------|----------------------------| | 存储内容 | 只读字符串常量 | 全局变量、静态变量、常量 | | 可修改性 | 不可修改 | 变量可修改常量不可修改 | | 作用域 | 无作用域概念(只读数据) | 全局或静态作用域 | | 内存管理 | 系统自动分配/释放 | 系统自动分配/释放 | --- ### 四、实际代码验证 ```c #include <stdio.h> char *test1() { char *p = "abc"; // 字符常量区 return p; } char *test2() { char p[] = "abc"; // 栈(局部数组) return p; // 返回悬空指针! } int main() { char *p = test1(); char *q = test2(); // q指向已释放的栈内存 printf("%s\n", p); // 输出"abc"(常量区有效) printf("%s\n", q); // 输出乱码(访问非法内存)[^1] return 0; } ``` --- ### 五、应用场景 - **字符常量区**:存储固定不变的字符串(如配置信息、错误提示)。 - **全局**:存放需全局访问的数据(如配置参数、单例对象)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值