多重指针--函数外申请动态内存

一、申请动态内存函数 int apply_memory(const char **pcDesAddr, const int len):

/*************************************************
  Function:    	int apply_memory(const char **pcDesAddr, const int len)
  Description:	申请动态内存
  Input:        len:申请内存大小
  Output:      	**pcDesAddr:动态内存地址
  Return:		-1:失败
                0:成功
*************************************************/
int apply_memory(const char **pcDesAddr, const unsigned int len)
{
	if (!(*pcDesAddr = (char *)malloc(len)))
	{
		printf("Apply [%d] memory FAIL!\n");
		return -1;
	}
	return 0;
}

输入:

1、const unsigned int len:函数需要申请动态内存大小;

输出:

1、const char **pcDesAddr:动态内存首地址;

    char** 是一个指向char*的指针。在函数中如果要对一个参数char *申请空间,同时要在函数外面使用。需要传递char**,否则申请的空间无法在函数外面使用,但申请的空间仍会在,造成空间泄露。

二、调用过程

int main()
{

	char *p
<think>我们被要求避免对指针使用sizeof,原因在于指针的大小与它所指向的数据类型的大小是两个不同的概念,且指针大小在不同平台或编译环境下可能不同。 以下是详细解释: ### 为什么避免对指针使用 sizeof? 1. **指针大小固定,与指向对象大小无关** 指针本身存储的是内存地址,其大小由系统架构决定: - 32位系统:固定4字节 - 64位系统:固定8字节 而 `sizeof(指针)` 返回的是指针变量本身占用的内存大小,**不是它指向的数据块大小**。 2. **常见错误场景** ```c int array[10]; int* ptr = array; // 错误:计算数组元素个数 size_t element_count = sizeof(ptr) / sizeof(int); // 结果错误!因为 sizeof(ptr) 是指针大小 ``` 正确做法应直接对数组使用 `sizeof`: ```c size_t element_count = sizeof(array) / sizeof(array[0]); // 正确:40/4=10 ``` 3. **动态内存分配陷阱** ```c int* dyn_array = malloc(10 * sizeof(int)); size_t size = sizeof(dyn_array); // 返回指针大小(4或8字节),非实际分配内存 ``` 4. **结构体大小误判** ```c struct Data { int* values; size_t count; }; void bad_copy(struct Data* src) { struct Data dest; memcpy(&dest, src, sizeof(src)); // 错误:只复制了指针值,未复制指向的数据 } ``` 5. **多态类型混淆** C++中基类指针指向派生类对象: ```cpp class Base { virtual void foo() {} }; class Derived : public Base { int data[100]; }; Base* obj = new Derived(); size_t s1 = sizeof(*obj); // 错误:得到Base类大小(可能含虚表指针) size_t s2 = sizeof(Derived); // 正确:整个派生类大小 ``` ### 正确使用指针 sizeof 的场景 | **适用场景** | **示例代码** | **说明** | |-------------------------------|---------------------------------------|------------------------------| | 获取指针变量存储空间大小 | `sizeof(char*)` | 用于内存分配计算 | | 平台兼容性检查 | `static_assert(sizeof(void*)==8, "需64位系统");` | 确保运行环境符合要求 | | 计算指针数组大小 | `char* words[] = {"A", "B", "C"}; sizeof(words)/sizeof(char*)` | 数组元素个数(3) | ### 替代方案指南 1. **数组大小计算** 使用编译时计算(仅适用于静态数组): ```c #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) ``` 2. **动态内存管理** 显式记录内存块大小: ```c size_t element_count = 100; int* buffer = malloc(element_count * sizeof(int)); ``` 3. **结构体内存复制** 深拷贝替代浅拷贝: ```c struct Data* deep_copy(const struct Data* src) { struct Data* dest = malloc(sizeof(struct Data)); dest->count = src->count; dest->values = malloc(dest->count * sizeof(int)); memcpy(dest->values, src->values, dest->count * sizeof(int)); return dest; } ``` 4. **C++多态对象操作** 使用虚函数或类型识别: ```cpp class Base { public: virtual size_t actual_size() const = 0; }; class Derived : public Base { size_t actual_size() const override { return sizeof(Derived); } }; ``` ### 特殊注意事项 - **函数指针**:`sizeof(函数指针)` 返回指针大小,但函数本身大小无意义 - **空指针**:`sizeof(NULL)` 通常返回指针大小,但标准未强制规定 - **C++成员指针**:成员指针大小可能大于普通指针(如多重继承场景) §§相关问题§§ 1. 如何安全地获取C语言中动态分配数组的元素数量? 2. 在C++中,sizeof(多态基类指针)和sizeof(派生类对象)有何本质区别? 3. 指针运算与数组索引转换时需要注意哪些sizeof相关陷阱? 4. 为什么函数指针使用sizeof可能产生未定义行为? 5. 在结构体包含柔性数组成员时如何正确计算总内存大小?</think>### 避免对指针使用 `sizeof` 的关键原因 在 C/C++ 开发中,对指针使用 `sizeof` 操作符是常见但危险的操作,主要原因如下: #### 1. **指针大小 ≠ 指向数据大小** ```c int array[100]; int* ptr = array; printf("指针大小: %zu\n", sizeof(ptr)); // 输出 4 或 8(指针本身大小) printf("数组大小: %zu\n", sizeof(array)); // 输出 400(100*4字节) ``` - **陷阱**:`sizeof(ptr)` 返回指针变量的大小(固定 4/8 字节),而非指向数据的大小 - **后果**:动态分配内存时无法通过 `sizeof` 获取实际内存块大小 #### 2. **平台依赖性陷阱 ```c // 32位系统:指针4字节,64位系统:指针8字节 size_t pointer_size = sizeof(void*); // 错误的内存分配计算 void* buffer = malloc(10 * sizeof(void*)); // 32位:40字节,64位:80字节 ``` - 相同代码在不同平台产生不同行为 -指针类型变更时(如 `int*` → `long*`)引发隐蔽错误 #### 3. **结构体大小误判 ```c struct Data { int id; char* name; // 指针成员 }; printf("结构体大小: %zu\n", sizeof(struct Data)); // 输出 8 或 16(包含填充字节),而非实际数据大小 ``` - 无法通过 `sizeof` 获取指针成员指向的实际数据大小 - 结构体复制时仅复制指针值,不复制指向的数据 #### 4. **多态对象识别失败 (C++) ```cpp class Base { virtual void foo() {} }; class Derived : public Base { int data[100]; }; Base* obj = new Derived(); size_t size = sizeof(*obj); // 返回Base类大小(虚表指针大小),非实际对象大小 ``` - 输出错误结果(通常 4-16 字节),而非实际 `Derived` 对象大小(约 400 字节) - 破坏多态性原则,无法识别实际对象类型 #### 5. **函数指针的未定义行为 ```c void (*func_ptr)(int) = some_function; size_t size = sizeof(func_ptr); // 返回指针大小 size_t invalid = sizeof(*func_ptr); // 未定义行为!函数类型无明确大小 ``` - C/C++ 标准未定义函数类型的大小 - 可能导致编译器错误或运行时崩溃 ### 正确替代方案 #### 1. 动态内存分配记录 ```c // 显式记录分配大小 size_t element_count = 100; int* dyn_array = malloc(element_count * sizeof(int)); // 通过元数据获取 struct MemoryBlock { size_t size; char data[]; }; ``` #### 2. 数组长度计算(仅静态数组) ```c int static_array[50]; size_t array_length = sizeof(static_array) / sizeof(static_array[0]); // 正确:50 ``` #### 3. C++ 运行时类型识别 ```cpp // typeid 获取类型信息 Derived* d = new Derived(); size_t real_size = typeid(*d).hash_code(); // 或使用自定义类型系统 // C++17 std::variant 安全访问 std::variant<Base*, Derived*> v = new Derived(); size_t size = std::visit([](auto* ptr){ return sizeof(*ptr); }, v); // 安全获取实际类型大小 ``` #### 4. 内存管理最佳实践 ```mermaid graph LR A[申请内存] --> B[记录分配大小] B --> C[返回数据指针] C --> D[使用内存] D --> E{需要大小?} E -->|是| F[查询元数据] E -->|否| G[继续使用] ``` ### 特殊注意事项 - **函数指针**:禁止使用 `sizeof(*func_ptr)` - **空指针解引用**:`sizeof(*null_ptr)` 虽合法但无意义 - **柔性数组**:`sizeof` 不包含尾部动态数据 - **位域结构**:`sizeof` 可能包含填充字节
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值