在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;
}
答案 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.
第三,您不使用name
或newname
。
问题(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)
,并返回ptr0
,ptr1
等中的一个。ptri->IndividualFile
相当于(*ptri).IndividualFile
,并返回i
政策对的文件名的基地址。