简体   繁体   English

Function 返回指向数组的指针 - 转换并获取值

[英]Function returning pointer to array - cast and get value

I have little dilemma with my code.我的代码几乎没有两难选择。

I have function which returns pointer (uint8_t*) to data buffer.我有 function 它将指针(uint8_t *)返回到数据缓冲区。 Is it possible and legal to cast this pointer to uint16_t when I need 2 values from array as uint16_t?当我需要数组中的 2 个值作为 uint16_t 时,将此指针转换为 uint16_t 是否可行且合法? Or there will be problem with aligning?还是对齐会有问题? Buffer is filled via byte reading from I2C.通过从 I2C 读取字节来填充缓冲区。

The problem exists on MCU but when I try this with visualstudio, it´s ok.这个问题存在于 MCU 上,但是当我用 visualstudio 尝试这个时,没关系。 MCU - Hardfault MCU - 硬故障

uint8_t arr[8];

uint8_t * FuncReturnPointer(void)
{
     arr[0] = 0xEE;
     arr[1] = 0xFF;

     return arr;
}

main
{
     uint16_t val16 = 0;

     val16 = *(uint16_t*)FuncReturnPointer();
}

Is there something wrong/dangerous?有什么问题/危险吗?

There are two separate issues here:这里有两个单独的问题:

  • strict aliasing violation严格的混叠违规
  • possible alignment violation可能违反 alignment

Either of these can lead to various "interesting" phenomena.这些中的任何一个都可能导致各种“有趣”的现象。 I could bet that this is due to alignment violation, ie arr does not happen to reside at an address divisible by _Alignof(uint16_t) .我敢打赌,这是由于 alignment 违规,即arr不会恰好位于可被_Alignof(uint16_t)整除的地址。 The proper fix is to use either正确的解决方法是使用

  • arithmetic:算术:

     val16 = ((uint16_t)*address << 8) | (address);
  • memcpy : memcpy

     memcpy(&val16, address, sizeof (val16));

uint8_t, uint16_t, char etc. types in pointers actually tells the program to how to treat the value in the pointed address.指针中的 uint8_t、uint16_t、char 等类型实际上告诉程序如何处理指向地址中的值。 Your function "FuncReturnPointer" returns the address of the "arr" array which is a 8-bit type array.您的 function “FuncReturnPointer”返回“arr”数组的地址,该数组是一个 8 位类型的数组。 When you add (uint16_t *) type converter into that function what it does actaully is treat it as a 16-bit number and store it as 0x00EE not 0xEE.当您将 (uint16_t *) 类型转换器添加到 function 中时,它实际上是将其视为 16 位数字并将其存储为 0x00EE 而不是 0xEE。 Good practice would be something like this:好的做法是这样的:

main
{
     uint16_t val16 = 0; 
     uint8_t *address;

     address = FuncReturnPointer();  //this gets the address of the arr
     val16 = (*(address++)<<8) + (*address);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM