C语言char数组指针疑问:输出值含义及合法内存范围校验方法
问题解答
1. arr[1]小于arr[0]的原因及两个值的含义
你代码中初始化的字符数组存储的是字符串"hello",输出的两个值是对应字符的ASCII编码的十进制形式:
arr[0]对应字符串第一个字符h,ASCII码十进制值为104arr[1]对应字符串第二个字符e,ASCII码十进制值为101
字符e的ASCII码本身就小于h的ASCII码,所以会出现arr[1]值更小的情况,属于正常现象。
2. 校验数组是否在合法内存范围的实现方法
首先要注意:仅靠传入的数组指针无法判断整个数组是否越界,需要额外传入数组的长度参数,具体校验步骤如下:
- 引入标准头文件
<stdint.h>,使用其中定义的uintptr_t类型,该类型是C标准专门设计的、可以安全存储指针值的无符号整数类型,避免直接转int带来的精度丢失或类型不匹配问题。 - 修改
func1参数列表,增加数组长度入参,在校验时同时判断数组的起始地址和结束地址都落在合法区间内,参考代码如下:
#include <stdio.h> #include <stdint.h> // 题目给定的合法内存范围 #define LEGAL_MEM_START 0 #define LEGAL_MEM_END 1073741823 void func1(char *arr, size_t arr_len) { // 将指针转换为可比较的无符号整数 uintptr_t start = (uintptr_t)arr; // 计算数组最后一个字节的地址值,char类型占1字节,直接加长度减1即可 uintptr_t end = start + arr_len - 1; // 校验逻辑:uintptr_t是无符号类型,天然大于等于0,可省略起始地址下界判断 if (end <= LEGAL_MEM_END && start <= end) { printf("数组在合法内存范围内\n"); // 原有业务逻辑 printf("%d\n", arr[0]); printf("%d\n", arr[1]); } else { printf("数组超出合法内存范围\n"); } return; }
如果你只需要校验数组首地址是否合法,不需要判断整个数组的范围,可以省略长度参数,直接判断(uintptr_t)arr <= LEGAL_MEM_END即可,但这种方式无法避免数组后半段元素越出合法范围的问题,不推荐使用。
内容的提问来源于stack exchange,提问作者kake
相关产品推荐
相关产品推荐

