Поскольку я не могу прочитать ваш код с его чрезмерно длинными именами переменных и функций, я переписал нарушающую функцию следующим образом.Итак, мое первое предложение: используйте более короткие имена переменных.
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) указывает либо на то, что вы пытались сократить этот код, чтобы понять segfault, либо на то, что вы не совсем точно знаете, что должна делать эта функция.
Остальная часть этого постаобъясняет вторую ошибку и ее исправление более подробно.
Вы правильно передали policies
как указатель на первый элемент массива SPFPolicyPair *
s.Итак, очень приблизительно
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
th политика пары.