异常的C指针行为
我有以下代码片段:异常的C指针行为,c,pointers,C,Pointers,我有以下代码片段: uint8_t *ptrconfig; uint8_t *ptrspi; ptrconfig = &TempDeviceConfig.ConfigSize; ptrspi = &spi_out_array[0]; for ( Count = 0U; Count < DEVICE_USER_SETTINGS_WORDCOUNT +1U; Count++ ) { *ptrspi++ = *ptrconfig++; } uint8\
uint8_t *ptrconfig;
uint8_t *ptrspi;
ptrconfig = &TempDeviceConfig.ConfigSize;
ptrspi = &spi_out_array[0];
for ( Count = 0U; Count < DEVICE_USER_SETTINGS_WORDCOUNT +1U; Count++ )
{
*ptrspi++ = *ptrconfig++;
}
uint8\u t*ptrconfig;
uint8_t*ptrspi;
ptrconfig=&TempDeviceConfig.ConfigSize;
ptrspi=&spi_out_数组[0];
用于(计数=0U;计数<设备\用户\设置\字计数+1U;计数++)
{
*ptrspi++=*ptrconfig++;
}
但是,第二行上的断点显示TempDeviceConfig.ConfigSize
的地址是0x2BD5
,但指针指向的地址是0x216F
为什么我会得到一个意外的指针值
编辑:
需要澄清的是,我无法确切说出TempDeviceConfig内部的内容,因为我需要注意internet上出现了多少代码,但它是一个结构,总共包含50多个字节,将通过SPI写入外部闪存芯片。我的目标是将结构复制到发送数据的SPI数组中
uint8_t *ptrconfig;
...
ptrconfig = &TempDeviceConfig.ConfigSize;
显然,TempDeviceConfig
是一个结构(或联合?),而ConfigSize
是类型为uint8\t
的成员
*ptrspi++ = *ptrconfig++;
ConfigSize
是单个uint8\t
对象。指针只能前进一次;然后,它指向刚好经过对象的位置,并且不能取消引用。您的代码假定ptrconfig
指向uint8\t
数组的一个元素。没有。在单个对象上循环是没有意义的
如果没有看到您正在使用的对象的声明,我猜不出代码应该做什么。但是,如果您想将整个结构(包括任何填充)复制到spi\u out\u数组中
,那么调用memcpy()
是一种更简单的方法。(将原始结构内容复制到外部接口可能非常容易出错,但如果写入的数据仅由当前系统读取,则可以。)
如果memcpy()
不可用,因为您正在为一个小型嵌入式系统编程,那么您可以轻松地将其作为函数或内联代码实现。例如:
struct foo { /* ... */ } obj;
unsigned char out_array[sizeof obj]; // or perhaps bigger
unsigned char *from = (unsigned char*)&obj;
unsigned char *to = out_array; // or &out_array[0]
for (int i = 0; i < sizeof obj; i ++) {
*to++ = *from++;
}
struct foo{/*…*/}obj;
无符号字符输出数组[sizeof obj];//或者更大
无符号字符*from=(无符号字符*)&obj;
无符号字符*to=out_数组;//or out_数组[0]
对于(int i=0;i
我将out\u数组
定义为无符号字符的数组
,因为这是C语言中最可移植的1字节类型;对象的表示形式定义为无符号字符
值序列。但几乎可以肯定的是,您可以使用uint8\t
如果您的目标是将结构的整个表示形式复制为原始字节,那么引用特定成员是没有意义的;只需将整个结构视为一个字节序列
但首先检查您的实现是否支持
memcpy
(如果支持,则应在
中声明)。“独立实现”不需要支持任何标准库函数,但您的实现可能支持托管标准库的某些子集。如果它是一种类型,您将无法获取其地址。执行memcpy()的方法看起来过于复杂。memcpy(spi_out_array,&TempDeviceConfig.ConfigSize,DEVICE_USER_SETTINGS_WORDCOUNT+1);
似乎怀疑您正在从名为“config size”的变量中复制配置数据一个疯狂的猜测:去掉.ConfigSize
和+1U
。TempDeviceConfig
的声明是什么?你是如何确定TempDeviceConfig.ConfigSize
的地址的?实际上,你可以随意增加ptrconfig
,指针不知道它们是多大的对象重新引用is。过了一段时间,试图取消引用它会带来垃圾,然后最终导致seg错误。@JeremyP:如果ptrconfig
指向一个对象,则多次增加它,或者只增加一次并取消引用它,则具有未定义的行为。(最坏的结果是它似乎“起作用”。)需要澄清的是,我不能确切说出TempDeviceConfig中的内容,因为我需要注意在internet上出现了多少代码,但它是一个结构,总共包含50多个字节,将通过SPI写入外部闪存芯片。我的目标是将该结构复制到SPI阵列中,然后发送数据。@user3628620:好的,但是TempDeviceConfig.ConfigSize
是一个uint8\u t
,对吗?为什么要尝试迭代单个uint8\u t
对象?@Deamonata:可能会这样做——如果碰巧没有填充。分配结构的地址(转换为uint8\u t*
)可能是有意义的如果要复制整个结构,请转到ptrconfig
。ConfigSize
是结构的第一个声明成员吗?请参阅我更新答案的最后一段。