2010-04-25 122 views
0

在对strncpy的调用中出现segfaults后面的代码,我看不到我做错了什么。我需要另一双眼睛来看这个。基本上,我试图分配一个指向struct的指针数组元素指向的结构的内存。将指针传递给struct C中的函数的问题

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

当您发布代码时,请将其缩进四个字符以使其格式正确。 – 2010-04-25 18:17:34

回答

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

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

将该函数更改为例如返回新分配的内存,并且代替

CreateIndividualPolicyListing((CurrentPolicyPair[i])); 

CurrentPolicyPair[i] = CreateIndividualPolicyListing(); 
+0

感谢您的帮助 – user325490 2010-04-25 19:08:17

1

问题是在函数原型:

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

功能得到一个NULL指针值,将它设置为malloc有效的位置,但不以任何方式将其返回给调用函数。 应该

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

更改函数以返回分配的指针更具惯用性。即,PolicyPair * SPFCreateIndividualPolicyListing(void)'。 – 2010-04-25 19:22:23

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策略对的文件名称。