C指针和内存分配:Realloc数组和指针传递
对于有C经验的人来说,这将是一个简单的内存分配/引用问题: 以下是我的数据结构:C指针和内存分配:Realloc数组和指针传递,c,pointers,memory-management,reference,C,Pointers,Memory Management,Reference,对于有C经验的人来说,这将是一个简单的内存分配/引用问题: 以下是我的数据结构: struct configsection { char *name; unsigned int numopts; configoption *options; }; typedef struct configsection configsection; struct configfile { unsigned int numsections; configsection *
struct configsection {
char *name;
unsigned int numopts;
configoption *options;
};
typedef struct configsection configsection;
struct configfile {
unsigned int numsections;
configsection *sections;
};
typedef struct configfile configfile;
以下是初始化configsection或configfile以及将configsection添加到configfile的例程:
// Initialize a configfile structure (0 sections)
void init_file(configfile *cf) {
cf = malloc(sizeof(configfile));
cf->numsections = 0;
}
// Initialize a configsection structure with a name (and 0 options)
void init_sec(configsection *sec, char *name) {
sec = malloc(sizeof(configsection));
sec->numopts = 0;
sec->name = name;
printf("%s\n", sec->name);
}
// Add a section to a configfile
void add_sec(configfile *cf, configsection *sec) {
// Increase the size indicator by 1
cf->numsections = cf->numsections + 1;
// Reallocate the array to accommodate one more item
cf->sections = realloc(cf->sections, sizeof(configsection)*cf->numsections);
// Insert the new item
cf->sections[cf->numsections] = *sec;
}
我相信我的问题源于我的init_sec函数。以下是一个例子:
int main(void) {
// Initialize test configfile
configfile *cf;
init_file(cf);
// Initialize test configsections
configsection *testcs1;
init_sec(testcs1, "Test Section 1");
// Try printing the value that should have just been stored
printf("test name = %s\n", testcs1->name);
尽管init_sec中的printf成功地打印了我刚才存储在configsection中的名称,但在main的printf中尝试相同的操作会产生分段错误。此外,addsec产生分段错误 您需要传递要更新的值的指针。。。例如:
// Initialize a configfile structure (0 sections)
void init_file(configfile **cf) {
*cf = malloc(sizeof(configfile));
(*cf)->numsections = 0;
}
configfile *var;
init_file(&var);
printf("%d\n", var->numsections);
否则,您只是更新本地指针*cf,而不是原始传入值在任何时候都不初始化cf->sections,这意味着当您第一次尝试重新锁定它时,您传递的是垃圾。添加:
cf->sections = NULL;
初始化文件应该有帮助
您也没有检查任何返回代码,但您知道是吗?此例程应该是
void init_file(configfile **cf) {
*cf = malloc(sizeof(configfile));
(*cf)->numsections = 0;
(*cf)->sections = NULL; // You forgot to initialise this.
}
i、 e.由init_文件&myconfigfilepointer调用;因此malloc返回值被传回
需要对init_sec执行相同的技巧
此功能不正确-这是一个已更正的版本
void add_sec(configfile *cf, configsection *sec) {
// Increase the size indicator by 1
// Reallocate the array to accommodate one more item
cf->sections = realloc(cf->sections, sizeof(configsection)*(1 + cf->numsections));
// Insert the new item
cf->sections[cf->numsections] = *sec; // Since arrays start at 0
cf->numsections = cf->numsections + 1;
}
然后需要调整main中的调用是的,init_sec中存在问题 您只是在这里复制name指针,这意味着它指向name的原始存储。如果你这样叫init_sec
configsection foobar()
{
configsection sec;
char name[80];
get_name(name);
init_sec(sec, name);
return sec;
}
foobar返回时,名称指针变为无效。您需要复制字符串并保留您的私人副本。在init_sec中:
但还有更多。在init_sec的第一行中,您将用malloc的指针覆盖传递给init_sec的指针。因此,新指针永远不会传递回被调用方。或者使用指向指针的指针,根本不使用configsection指针毕竟,您正在分配,只需返回已分配的指针:Complete corrected function:
// Initialize a configsection structure with a name (and 0 options)
configsection* init_sec(char *name) {
configsection *sec = malloc(sizeof(configsection));
sec->numopts = 0;
sec->name = name;
printf("%s\n", sec->name);
return sec;
}
您需要重新思考函数参数在C中的传递方式以及指针是什么。您的问题与内存分配无关。相反,您的代码只是将指向动态分配内存的指针分配给一个局部变量,而调用代码对此一无所知 虽然您可以通过将指针传递到调用方的指针(即双指针)来解决问题,但这不一定是最优雅或最常用的处理方式。相反,您应该从函数返回分配结果。在进行此操作时,还应该使用calloc立即将内存归零。总而言之:
typedef struct substuff_
{
int a;
double b;
} substuff;
typedef struct stuff_
{
unsigned int n;
substuff * data;
} stuff;
substuff * init_substuff()
{
substuff * const p = malloc(sizeof *p);
if (p) { p->a = 5; p->b = -0.5; }
return p;
}
stuff * init_stuff()
{
substuff * const p = init_substuff();
if (!p) return NULL;
stuff * const q = malloc(sizeof *q);
if (q) { q->n = 10; q->data = p; }
return q;
}
作为练习,您应该编写相应的函数void free_substuffsubstuff*和void free_stuff* @IntermediateHacker:谢谢。这有什么原因吗?嗯,如果你只是使用标准C,不是这样。但是有时候,使用GObject等,它可能会导致问题。。。到达那里*cf->numsections=0;生成一个非结构或联合错误。为答案添加了操作顺序,请尝试。此答案完全错误。您需要*cf->numsections=0或*cf.numsections=0-它们是等效的-而不是两者的组合。更新:我的错误-见下文。@Geoffrey:哦,是的!我以前见过!谢谢你。@Tim-我以为我已经修好了???这不是完全错误,这是语法错误,*cf.numsections无效,它是指向定义中指针的指针。呵呵,我也错过了这一个+1:添加了以下内容:*cf->sections,我认为这可能是解决方案。啊,是的。您注意到我错误地分配了数组值。杰出的是的,这似乎是正确的。如果我试图在初始化函数之外访问name值,那么我只会得到null。@thoughtadvances:对不起,我过早地单击了“回答”。你有两个问题。一个是不重复的名称字符串,另一个是分配内存的字符串,但从不传回指针。我发现在双指针情况下很难跟踪指向的内容。我将尝试实现这一点。
// Initialize a configsection structure with a name (and 0 options)
configsection* init_sec(char *name) {
configsection *sec = malloc(sizeof(configsection));
sec->numopts = 0;
sec->name = name;
printf("%s\n", sec->name);
return sec;
}
typedef struct substuff_
{
int a;
double b;
} substuff;
typedef struct stuff_
{
unsigned int n;
substuff * data;
} stuff;
substuff * init_substuff()
{
substuff * const p = malloc(sizeof *p);
if (p) { p->a = 5; p->b = -0.5; }
return p;
}
stuff * init_stuff()
{
substuff * const p = init_substuff();
if (!p) return NULL;
stuff * const q = malloc(sizeof *q);
if (q) { q->n = 10; q->data = p; }
return q;
}