我有结构参数。我想初始化它们中的每一个并将它们的地址放入paramList数组和paramListSize字段中的初始化参数数量。我想要实现这一点,而不是预先指定params的数量,并尽可能少地执行步骤。
我写了一些我很满意的解决方案,但它并没有真正起作用:-)第二个元素被随机数覆盖,我不明白为什么。
你能帮我吗?
我正在使用C ++编译器,但用C语言编写。
这是代码和沙箱https://repl.it/repls/SourRoughDrawing
#include "stdio.h"
struct parameter
{
int field;
};
struct configuration {
parameter** paramList;
int paramListSize;
parameter param1;
parameter param2;
parameter param3;
};
parameter *initParameter(parameter *param, int value, int *paramListSize)
{
param->field = value;
(*paramListSize)++;
return param;
}
int initConfig(configuration *config)
{
config->paramListSize = 0;
parameter* test[] =
{
initParameter(&config->param1, 100, &config->paramListSize),
initParameter(&config->param2, 200, &config->paramListSize),
initParameter(&config->param3, 300, &config->paramListSize)
};
config->paramList = test;
// dirty failed attemp to fix :-)
for (int parameterIndex = 0; parameterIndex < config->paramListSize; parameterIndex++)
{
config->paramList[parameterIndex] = test[parameterIndex];
}
}
void printConfig(configuration *config)
{
for (int parameterIndex = 0; parameterIndex < config->paramListSize; parameterIndex++)
{
printf("param%d:%d\n", parameterIndex + 1, config->paramList[parameterIndex]->field);
}
}
int main(void)
{
configuration config;
initConfig(&config);
printConfig(&config);
}
你的方法的问题是test
是一个分配的局部变量和堆栈,它将在int initConfig(configuration *config)
返回后消失。
所以这个尝试
config->paramList = test;
必须用内存的分配来代替,这将在函数返回后继续存在。
config->paramList = (parameter**)calloc(config->paramListSize, sizeof(parameter));
现在你可以将在temp
收集的指针复制到paramList
for (int i = 0; i< config->paramListSize; i++)
{
config->paramList[i] = test[i];
}
我们还检查内存分配是否成功,并相应地从0
返回-
或int initConfig
1。
在main
结束时,内存被释放。
该计划遵循您的想法:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
struct parameter
{
int field;
};
struct configuration {
parameter** paramList;
int paramListSize;
parameter param1;
parameter param2;
parameter param3;
};
parameter *initParameter(parameter *param, int value, int *paramListSize)
{
param->field = value;
(*paramListSize)++;
return param;
}
int initConfig(configuration *config)
{
config->paramListSize = 0;
// This array gathers the parameter pointers but it will be lost when `initConfig` returns:
parameter* test[] =
{
initParameter(&config->param1, 100, &config->paramListSize),
initParameter(&config->param2, 200, &config->paramListSize),
initParameter(&config->param3, 300, &config->paramListSize)
};
// Allocate memory for the list of parameters:
config->paramList = (parameter**)calloc(config->paramListSize, sizeof(parameter));
if (config->paramList == NULL) // calloc failed
return -1;
// copy the pointers to the paramList
for (int i = 0; i< config->paramListSize; i++)
{
config->paramList[i] = test[i];
}
return 0;
}
void printConfig(configuration *config)
{
for (int i= 0; i < config->paramListSize; i++)
{
printf("param %d = %d\n", i + 1, config->paramList[i]->field);
}
}
int main(void)
{
configuration config;
if( initConfig(&config) == 0){ // initConfig returned with success
printConfig(&config);
free(config.paramList); // free the memory.
}
else {
printf("calloc failed - initConfig failed!\n");
}
return 0;
}
输出:
param 1 = 100
param 2 = 200
param 3 = 300
你没有为paramlist
分配内存;相反,你指定一个指向局部变量的指针,一旦它的生命周期在函数结束时变为无效。然后访问它是未定义的行为。
以下代码显示了如何克服此问题;
int initConfig(configuration *config)
{
config->paramListSize = 0;
config->paramList = calloc(3, sizeof(parameter));
config->paramList[0] = &config->param1;
config->paramList[1] = &config->param2;
config->paramList[2] = &config->param3;
initParameter(&config->param1, 100, &config->paramListSize);
initParameter(&config->param2, 200, &config->paramListSize);
initParameter(&config->param3, 300, &config->paramListSize);
}