在C语言中,函数之间传递指向结构的指针数组时出现的问题

在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

调用strncpy时segfaults后面的代码,我看不出我做错了什么。我需要另一双眼睛来观察它。本质上,我试图为一个结构分配内存,该结构由指向该结构的指针数组中的元素指向

#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 | ... ]