2010-04-25 3 views
0

strncpy 호출시 segfaults 다음에 오는 코드와 내가 잘못하고있는 것을 볼 수 없습니다. 나는 이것을 보는데 또 다른 눈이 필요하다. 본질적으로 구조체에 대한 포인터의 배열에있는 요소에 의해 가리키는 구조체에 메모리를 할당하려고합니다. 단지 로컬 IndividualPolicyPairtoCreate 변수에 할당C에서 함수 중 struct에 대한 포인터 배열을 전달할 때의 문제

#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

, 네 개의 문자로를 들여주십시오. –

답변

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

는 - C 값 통과가 참조로 전달하지 않다. 메모리가 누출되고 호출자가 전달하는 구조체에 변경 사항이 표시되지 않습니다.

새로 할당 된 메모리를 반환하고 대신

CreateIndividualPolicyListing((CurrentPolicyPair[i])); 

CurrentPolicyPair[i] = CreateIndividualPolicyListing(); 
+0

도움을 주셔서 감사합니다 – user325490

1

문제는 함수의 프로토 타입에 수행

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

함수는, NULL 포인터의 값을 가져옵니다로 설정 유효한 위치는 malloc하지만 어떤 식 으로든 호출 함수로 반환하지 않습니다. 다음과 같이 나는 그것 과도하게 긴 변수와 함수 이름으로 코드를 읽을 수 없기 때문에 그것은

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

할당 포인터를 반환하는 함수를 변경하는 것이 훨씬 더 관용적입니다. 즉, 'PolicyPair * SPFCreateIndividualPolicyListing (void)'입니다. –

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); 

    } 
} 

이 코드에는 여러 가지 문제가 있습니다. C 순수 값으로 전달되기 때문에 우선

다른 지적했듯이 create_policy(policies[i])policies[i]의 값을 변경할 수 없다.

polices[i] = create_policy(); 

로 작성하고 할당 정책 쌍의 주소를 반환 create_policy을 변경합니다.

둘째, (*policies)[i].IndividualFile은 (는)입니다. 그것은 당신이 name 또는 newname를 사용하지 않는

(*policies[i]).IndividualFile 

또는 더 나은

policies[i]->IndividualFile. 

셋째, 해야합니다.

문제 (1)과 (2)는 둘 다 segfaults로 연결됩니다. 문제 (3)은 segfault를 이해하기 위해이 코드를 제거하려고 시도했거나이 함수가 수행해야하는 작업을 정확히 모르고 있음을 나타냅니다.


이 게시물의 나머지 부분에서는 두 번째 버그와 수정 사항에 대해 자세히 설명합니다.

policiesSPFPolicyPair * 어레이의 첫 번째 요소에 대한 포인터로 올바르게 전달했습니다. 그래서, 매우 약

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이 일련의 policy 쌍 오브젝트를 가리 키지 않는 한, 정확히 하나의 그러한 오브젝트를 가리 킵니다. 따라서 i이 0보다 크면 정의되지 않은 메모리를 참조하지 않게됩니다.

  • policies[i]*(policies + i)에 해당하고, ptr0, ptr1 중 하나를 반환 등
  • ptri->IndividualFile(*ptri).IndividualFile에 해당하고, 기본 주소를 반환

    개정 된 표현, policies[i]->IndividualFile는 다음과 같이 작동 i 번째 정책 쌍에 대한 파일 이름 당신이 코드를 게시 할 때 제대로 포맷 가도록 (듯이),

관련 문제