在C语言中,函数之间传递指向结构的指针数组时出现的问题
调用strncpy时segfaults后面的代码,我看不出我做错了什么。我需要另一双眼睛来观察它。本质上,我试图为一个结构分配内存,该结构由指向该结构的指针数组中的元素指向在C语言中,函数之间传递指向结构的指针数组时出现的问题,c,C,调用strncpy时segfaults后面的代码,我看不出我做错了什么。我需要另一双眼睛来观察它。本质上,我试图为一个结构分配内存,该结构由指向该结构的指针数组中的元素指向 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_POLICY_NAME_SIZE 64 #define POLICY_FILES_TO_BE_PROCESSED "SPFPolicyFilesR
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_POLICY_NAME_SIZE 64
#define POLICY_FILES_TO_BE_PROCESSED "SPFPolicyFilesReceivedOffline\0"
typedef struct TarPolicyPair
{
int AppearanceTime;
char *IndividualFile;
char *FullPolicyFile;
} PolicyPair;
enum {
bwlist = 0,
fzacts,
atksig,
rules,
MaxNumberFileTypes
};
void SPFCreateIndividualPolicyListing(PolicyPair *IndividualPolicyPairtoCreate )
{
IndividualPolicyPairtoCreate = (PolicyPair *) malloc(sizeof(PolicyPair));
IndividualPolicyPairtoCreate->IndividualFile = (char *)malloc((MAX_POLICY_NAME_SIZE * sizeof(char)));
IndividualPolicyPairtoCreate->FullPolicyFile = (char *)malloc((MAX_POLICY_NAME_SIZE * sizeof(char)));
IndividualPolicyPairtoCreate->AppearanceTime = 0;
memset(IndividualPolicyPairtoCreate->IndividualFile, '\0', (MAX_POLICY_NAME_SIZE * sizeof(char)));
memset(IndividualPolicyPairtoCreate->FullPolicyFile, '\0', (MAX_POLICY_NAME_SIZE * sizeof(char)));
}
void SPFCreateFullPolicyListing(SPFPolicyPair **CurrentPolicyPair, char *PolicyName, char *PolicyRename)
{
int i;
for(i = 0; i < MaxNumberFileTypes; i++)
{
CreateIndividualPolicyListing((CurrentPolicyPair[i]));
// segfaults on this call
strncpy((*CurrentPolicyPair)[i].IndividualFile, POLICY_FILES_TO_BE_PROCESSED, (SPF_POLICY_NAME_SIZE * sizeof(char)));
}
}
int main()
{
SPFPolicyPair *CurrentPolicyPair[MaxNumberFileTypes] = {NULL, NULL, NULL, NULL};
int i;
CreateFullPolicyListing(&CurrentPolicyPair, POLICY_FILES_TO_BE_PROCESSED, POLICY_FILES_TO_BE_PROCESSED);
return 0;
}
#包括
#包括
#包括
#定义最大策略名称大小64
#定义要处理的策略文件“SPFPolicyFilesReceivedOffline\0”
typedef结构TarPolicyPair
{
内显时间;
字符*个人文件;
char*FullPolicyFile;
}保单对;
枚举{
bwlist=0,
fzacts,
atksig,
规则,
MaxNumberFileType
};
void SPFCreateIndividualPolicyList(PolicyPair*IndividualPolicyPairtoCreate)
{
IndividualPolicyPairtoCreate=(PolicyPair*)malloc(sizeof(PolicyPair));
IndividualPolicyPairtoCreate->IndividualFile=(char*)malloc((MAX_POLICY_NAME_SIZE*sizeof(char));
IndividualPolicyPairtoCreate->FullPolicyFile=(char*)malloc((MAX_POLICY_NAME_SIZE*sizeof(char));
IndividualPolicyPairtoCreate->AppearanceTime=0;
memset(IndividualPolicyPairtoCreate->IndividualFile,'\0',(最大策略名称大小*大小(字符));
memset(IndividualPolicyPairtoCreate->FullPolicyFile,'\0',(最大策略名称大小*大小(字符));
}
void SPFCreateFullPolicyList(SPFPolicPair**CurrentPolicyPair,char*PolicyName,char*PolicyRename)
{
int i;
对于(i=0;i
只分配给本地IndividualPolicyPairtoCreate变量-C的是按值传递,而不是按引用传递。您正在泄漏内存,调用方将看不到您传入的结构的任何更改
将该函数更改为,例如,返回新分配的内存,而不是
CreateIndividualPolicyListing((CurrentPolicyPair[i]));
做
问题在于功能的原型:
...
void SPFCreateIndividualPolicyListing(PolicyPair *IndividualPolicyPairtoCreate )
{
...
函数获取空指针值,通过malloc将其设置为有效位置,但不会以任何方式将其返回给调用函数。
应该是
...
void SPFCreateIndividualPolicyListing(PolicyPair **IndividualPolicyPairtoCreate )
{
*IndividualPolicyPairtoCreate = malloc (...);
...
因为我无法读取带有过长变量和函数名的代码,所以我将有问题的函数重写如下。因此,我的第一个建议是:使用更短的变量名
void create_policies(SPFPolicyPair **policies, char *name, char *newname) {
int i;
for(i = 0; i < MaxNumberFileTypes; i++) {
create_policy(policies[i]);
strncpy((*policies)[i].IndividualFile, POLICY_FILES_TO_BE_PROCESSED, SPF_POLICY_NAME_SIZE);
}
}
并更改create_policy
以返回它分配的策略对的地址
其次,(*策略)[i]。个人文件
是错误的。应该是
(*policies[i]).IndividualFile
甚至更好
policies[i]->IndividualFile.
第三,您不使用name
或newname
问题(1)和(2)都会导致SEG故障。问题(3)表明您一直在尝试剥离此代码以了解segfault,或者您不确定此函数应该做什么
本文的其余部分将更详细地解释第二个bug及其修复 您已正确地将
策略作为指向spfpolicPair*
s数组的第一个元素的指针传入。所以,非常粗略地说
policies --> [ ptr0 | ptr1 | ptr2 | ... ]
每个ptri
值都是一个SPFPolicPair*
。有两种方法可以解释此类值:(a)spfpolicPair
对象数组的基,或(b)指向单个此类对象的指针。语言本身并不关心您使用的是哪种解释,但在您的例子中,通过查看您如何初始化策略
数组,显然是案例(b)
那么,评估((*策略)[i])单个文件如何出错
*策略
从上图返回ptr0
- 该值现在被下标为
ptr0[i]
问题的第一个迹象是,您只使用了策略[0]
,然后将此值ptr0
视为指向全尺寸策略对对象数组的第一个元素的指针,例如
ptr0 -> [ ppair0 | ppair1 | ppair2 | ... ]
这是您正在索引的数组。除了ptr0
没有指向策略对对象序列之外,它只指向一个这样的对象。因此,只要i
大于零,就可以停止引用未定义的内存
修改后的表达式,policies[i]->IndividualFile
,工作原理如下:
策略[i]
相当于*(策略+i)
,并返回ptr0
、ptr1
等中的一个
ptri->IndividualFile
相当于(*ptri).IndividualFile
,并返回i
th策略对的文件名的基址
发布代码时,请将其缩进四个字符,以便正确格式化。更改函数以返回分配的指针更为惯用。例如,PolicyPair*spfcreateIndividualPolicyList(void)
。
policies[i]->IndividualFile.
policies --> [ ptr0 | ptr1 | ptr2 | ... ]
ptr0 -> [ ppair0 | ppair1 | ppair2 | ... ]