我有一个结构数组作为函数参数,并且数组的大小是动态的。我的同事说,我必须使用一个双指针,因为结构数组中包含的值将被覆盖。
将成为双指针的参数如下:
xPIDConfig_t **pxPIDConfig下面是xPIDConfig_t的结构:
typedef struct
{
ePIDType_t ePIDType;
/* Common fields for the different types of PID */
float fLowerSaturationLimit;
float fUpperSaturationLimit;
float fOldInput;
float fIError;
uint32_t ulDeltaTime;
eBool_t bSaturationEnable;
eBool_t bAntiWindupEnable;
eBool_t bNegativeErrorEmptyIError;
union
{
/* Parallel PID fields */
struct
{
float fProportionalGain;
float fIntegralGain;
float fDerivativeGain;
}xParallelPID;
/* Non-interactive PID fields */
struct
{
float fControllerGain;
uint32_t ulIntegralTime;
uint32_t ulDerivativeTime;
}xNonInteractivePID;
}xUniqueFields;
}xPIDConfig_t;pxPIDConfig数组的大小将有所不同。
但是,我不知道如何对该双指针进行malloc,甚至不知道如何使用包含双指针的函数。
我只是想知道是否有人有一个很好的代码示例,说明如何使用具有可变大小的双指针数组的函数?以及如何正确地更改函数中数组本身中包含的值?
现在,我是如何更改函数中的值的:
pxPIDConfig->ePIDType = ePIDType;
pxPIDConfig->fOldInput = 0;
pxPIDConfig->fIError = 0;
pxPIDConfig->ulDeltaTime = ulDeltaTime;
pxPIDConfig->bSaturationEnable = bIsSaturationEnable;
pxPIDConfig->bAntiWindupEnable = bIsAntiWindupEnable;
pxPIDConfig->bNegativeErrorEmptyIError = bNegativeErrorEmptyIError; 当指针是双的,我必须使用双“->”吗?这让我很困惑。
谢谢大家的帮助
/*****************编辑*
我的函数现在正在工作,但是我被告知我需要使用内存分配,因为我的数组的大小取决于我想要实现的循环的数量。
下面是我的函数的参数:
eError_t eControlCascadeInit( uint8_t ucNumberOfLoops, ePIDType_t *pePIDType, xPIDConfig_t **pxPIDConfig, float *pfLowerLimit, float *pfUpperLimit, uint32_t *pulDeltaTime, \
eBool_t *pbIsSaturationEnable, eBool_t *pbIsAntiWindupEnable, eBool_t *pbNegativeErrorEmptyIError, \
float *pfPGain, float *pfIGain, float *pfDGain, float *pfCGain, uint32_t *pulITime, uint32_t *pulDTime )它们都是大小为ucNumberOfLoops的数组。它们都是只读数组,除了pxPIDConfig的只读数组.该函数通过数组将参数传递给函数,从而初始化数组中存在的所有xPIDConfig_t。
数组0包含正在初始化的第一个PID控制器的参数。
数组1包含被初始化的第二个PID控制器的参数,等等。
函数中的所有参数都是这样的。
希望这能让我的问题更清楚?
发布于 2021-06-08 16:46:51
这里有一个如何使用双指针来更改函数中指针的示例:
void allocate(xPIDConfig_t **array, size_t size)
{
*array = malloc(sizeof(**array) * size);
/* some examples how to access the struct members vi double pointer -*
(*array) -> ulDeltaTime = 100;
(**array).ulDeltaTime = 100;
(*(array + 5)) -> ulDeltaTime = 100;
array[5] -> ulDeltaTime = 100;
(*array[5]).ulDeltaTime = 100;
}
int main(void)
{
xPIDConfig_t *array;
allocate(&array, 100);
printf("%s\n", array ? "success" : "failure");
free(array);
}发布于 2021-06-08 16:51:14
仅限于讨论关于您的标题问题的假设和问题:
“如何为标准C中的结构数组正确使用双指针(指针指向指针)”
首先,仅仅因为函数参数可能有一个双指针(即xPIDConfig_t **pxPIDConfig),并不意味着需要用双指针为变量分配内存,也就是说,如果函数例如是这样调用的:funcChangeParam(&pxPIDConfig); --这通常意味着要传递的对象需要以某种方式进行更改,要求传递地址,而不是对象本身。另外,如果对象本身是指针(例如指向struct对象的多个实例的指针)。然后,用于传递对象以进行修改的函数将使用参数(如void funcChangeParam(xPIDConfig_t **pxPIDConfig); (注意这里的双指针)进行原型化。
因此,通过这个函数原型,内存的分配如下所示:
void funcChangeParam(xPIDConfig_t **pxPIDConfig);
//allocate memory for multiple instances of struct
xPIDConfig_t *pxPIDConfig = malloc(countOfInstances * sizeof(*pxPIDConfig);
if(pxPIDConfig)
{
//use pxPIDConfig
funcChangeParam(&pxPIDConfig);pass pointer to multiple instances of struct调用函数中对对象成员的引用可以使用以下符号。例:
//in a loop or other construct where i is defined from 0 to countOfInstances - 1
(*pxPIDConfig)[i].ePIDType = ePIDType;//modification of assignment per your example
//etc.
//The following is a trivial example for illustration purposes.
//Code here uses a simplified struct, function
//prototype, and simple calling example, the concept
//of which easily translates to what you are
//asking about.
typedef struct {
int num;
}test_s;
void change(test_s **new);
int main(){
test_s *test = malloc(10*sizeof *test);
change(&test);
return 0;
}
void change(test_s **new)
{
for(int i=0;i<10;i++)
{
(*new)[i].num = (i+1)*3; //init all instances to some value
}
}发布于 2021-06-08 17:17:22
如果函数将数组重新分配到不同的大小,则只需要一个双指针。如果大小没有变化,您只需将指针传递到数组的(通常是第一个)元素,以及函数所需的任何大小或索引。例如:
extern void frobPidConfig(xPIDConfig_t *);
// 'frob' the xPIDConfig_t array elements from index a to b
void frobSomePidConfigs(xPIDConfig_t *pidconfigs, unsigned int a, unsigned int b)
{
unsigned int i;
for (i = a; i <= b; i++)
{
frobPidConfig(&pidConfigs[i]);
// Example of member access:
pidConfigs[i].ulDeltaTime = 42;
}
}调用代码示例:
xPIDConfig_t *pidConfigs;
unsigned int n = 10; // or whatever...
pidConfigs = calloc(sizeof *pidConfigs, n);
if (!pidConfigs)
{
// Allocation error
exit(1);
}
/* ... */
frobSomePidConfigs(pidConfigs, 2, 5);另一方面,如果函数需要重新分配数组并初始化任何新元素,则可以使用如下双指针来完成:
extern void initPidConfig(xPIDConfig_t *);
void reallocPidConfigs(xPIDConfig_t **pidConfigs, unsigned int oldSize, unsigned int newSize)
{
unsigned int i;
// Reallocate to new size
xPIDConfig_t *realloced = realloc(*pidConfigs, sizeof **pidConfigs * newSize);
if (newSize && !realloced)
{
// allocation error
exit(EXIT_FAILURE);
}
*pidConfigs = realloced;
// Initialize any additional elements
for (i = oldSize; i < newSize; i++)
{
initPidConfig(*pidConfigs + i); // or: initPidConfig(&(*pidConfigs)[i]);
// Examples of member access:
(*pidConfigs)[i].bSaturationEnable = true;
(*pidConfigs + i)->bAntiWindupEnable = true;
}
}调用代码示例:
xPIDConfig_t *pidConfigs = NULL;
// Note: realloc of the NULL pointer in *pidConfigs is OK.
reallocPidConfigs(&pidConfigs, 0, 10);
frobSomePidConfigs(pidConfigs, 2, 5);https://stackoverflow.com/questions/67891138
复制相似问题