在C中的函数之间传递指向struct的数组的问题

时间:2010-04-25 18:15:51

标签: c

在strncpy调用后跟随段错误的代码,我无法看到我做错了什么。我需要另一组眼睛看这个。本质上,我正在尝试为结构指针数组中的元素指向的结构分配内存。

#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;
}

3 个答案:

答案 0 :(得分:1)

问题出在功能原型中:

...
void SPFCreateIndividualPolicyListing(PolicyPair *IndividualPolicyPairtoCreate )
{
...

该函数获取NULL指针值,通过malloc将其设置为有效位置,但不以任何方式将其返回给调用函数。 它应该是

...
void SPFCreateIndividualPolicyListing(PolicyPair **IndividualPolicyPairtoCreate )
{
*IndividualPolicyPairtoCreate = malloc (...);
...

答案 1 :(得分:0)

void SPFCreateIndividualPolicyListing(PolicyPair *IndividualPolicyPairtoCreate )
{
  IndividualPolicyPairtoCreate = (PolicyPair *) malloc(sizeof(PolicyPair));

这只是分配给本地IndividualPolicyPairtoCreate变量 - C是按值传递,而不是按引用传递。您正在泄漏内存,并且调用者不会看到您传入的结构的任何更改。

将该功能更改为例如返回新分配的内存,而不是

 CreateIndividualPolicyListing((CurrentPolicyPair[i]));

CurrentPolicyPair[i] = CreateIndividualPolicyListing();

答案 2 :(得分:0)

因为我无法使用过长的变量和函数名读取代码,所以我重写了违规函数,如下所示。所以,我的第一个建议是:使用较短的变量名。

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(policies[i])无法更改policies[i] 的值,因为C纯粹是按值传递的。把它写成

polices[i] = create_policy();

并更改create_policy以返回其分配的策略对的地址。

其次, (*policies)[i].IndividualFile错误。它应该是

(*policies[i]).IndividualFile

甚至更好

policies[i]->IndividualFile.

第三,您不使用namenewname

问题(1)和(2)都会导致段错误。问题(3)表明您一直试图剥离此代码以理解段错误,或者您不确定该函数应该做什么。


本文的其余部分更详细地解释了第二个错误及其修复。

您已正确传入policies作为指向SPFPolicyPair *数组的第一个元素的指针。所以,非常粗略

policies --> [ ptr0 | ptr1 | ptr2 | ... ]

每个ptri值都是SPFPolicyPair *。有两种方法可以解释这样的值:(a)SPFPolicyPair个对象数组的基础,或(b)指向单个此类对象的指针。语言本身并不关心你使用哪种解释,但在你的情况下,通过查看你如何初始化policies数组,显然是情况(b)。

那么,评估((*policies)[i]).IndividualFile如何出错?

  • *policies从上图中返回ptr0
  • 该值现已下标,ptr0[i]

问题的第一个迹象是您只使用policies[0],然后将此值ptr0视为指向全尺寸策略对数组的第一个元素的指针对象,例如,

ptr0 -> [ ppair0 | ppair1 | ppair2 | ... ]

这是您要编制索引的数组。除了ptr0没有指向一系列策略对对象之外,它只指向一个这样的对象。因此,只要i大于零,就会引用未定义的内存。

修订后的表达式policies[i]->IndividualFile的作用如下:

  • policies[i]相当于*(policies + i),并返回ptr0ptr1等中的一个。
  • ptri->IndividualFile相当于(*ptri).IndividualFile,并返回i政策对的文件名的基地址。