为何`unsigned char buf[length]`与`unsigned char**`不兼容?求代码修正方案
问题解决:数组地址转
unsigned char**的编译错误与段错误 错误原因解析
你遇到的核心问题是对数组指针类型的误解:
- 数组名
buffer在多数场景下会退化为指向首元素的指针(类型unsigned char*),但&buffer取的是整个数组的地址,类型是unsigned char (*)[91],和函数要求的unsigned char**是完全不同的指针类型。 - 强制转换
(unsigned char**)&buffer会骗过编译器,但函数内部会把这个指针当作二级指针去解引用,实际访问的是错误的内存区域,直接导致段错误。
正确修改方案
方案1:用临时指针适配参数类型(已知缓冲区足够大)
如果确定91字节的缓冲区足够存储公钥,只需要加一个临时指针变量,让它承接数组退化后的指针,再取这个临时指针的地址传给函数:
unsigned char buffer[91]; unsigned char* ptr = buffer; // 数组退化为指向首元素的指针,类型匹配 ptrdiff_t length = i2d_PUBKEY(m_pkey, &ptr); // 注:函数执行后,ptr会指向buffer中已写入数据的下一个位置,length是实际写入的字节数
方案2:动态适配缓冲区大小(不确定所需长度时)
如果不确定公钥需要多大的缓冲区,可以先调用一次i2d_PUBKEY获取所需长度,再分配对应大小的内存:
// 第一次调用传入nullptr,获取所需的缓冲区长度 ptrdiff_t required_len = i2d_PUBKEY(m_pkey, nullptr); // 方式1:用std::vector分配内存(推荐,自动管理内存) std::vector<unsigned char> buffer(required_len); unsigned char* ptr = buffer.data(); ptrdiff_t length = i2d_PUBKEY(m_pkey, &ptr); // 方式2:用静态数组(C++11及以后支持变长数组,部分编译器需开启扩展) // unsigned char buffer[required_len]; // unsigned char* ptr = buffer; // ptrdiff_t length = i2d_PUBKEY(m_pkey, &ptr);
关键误区纠正
数组名的退化是有场景限制的:只有当数组名作为函数参数、赋值给指针变量、参与算术运算等场景时,才会退化为指向首元素的指针。但取数组的地址(&数组名)时,不会发生退化,得到的是指向整个数组的指针,它和二级指针(T**)没有任何隐式转换关系,强制转换必然导致内存访问错误。
内容的提问来源于stack exchange,提问作者Multisync
相关产品推荐
相关产品推荐

