2013-05-28 3 views
3

이 프로그램은 UNIX 시스템에서 seg 오류를 발생시킵니다. 나는 원인을 memset()의 두 번째 호출로 좁혔다.memset을 호출하면 분할 오류가 발생합니다.

왜이 문제가 발생합니까? 코드의 첫 번째 "덩어리"는 두 번째 코드와 거의 같습니다. 그렇지 않습니까? 왜 첫 번째 memset segfault를 호출하지 않았습니까?

segfaulting memset 호출과 관련된 다른 스레드를 살펴 보았지만 그 중 아무 것도 이와 유사하지 않았습니다.

왜 그런 간단한 프로그램을 작성했는지 궁금한 경우, 필자가 작성한 다른 프로그램에서 구조에 memcpy()를 적용하는 방법을 가르쳐 줬습니다.

#include <stdio.h> 
#include <stdlib.h> 

typedef struct{ 
    int x; 
    char text; 
} FilesStruct; 

int 
main(int argc, char** argv) 
{ 
    FilesStruct *old_dir; 
    memset(old_dir,0,sizeof(FilesStruct)); 
    old_dir->x = 3; 
    old_dir->text = 'c'; 
    printf("old dir: %d,%c\n",old_dir->x,old_dir->text); 

    FilesStruct *new_dir; 
    memset(new_dir,0,sizeof(FilesStruct)); 
    new_dir->x = 7; 
    new_dir->text = 'g'; 
    printf("new dir: %d,%c\n",new_dir->x,new_dir->text); 

    return 0; 
} 

답변

9
FilesStruct *old_dir; 
memset(old_dir,0,sizeof(FilesStruct)); 

시도는 초기화되지 않은 포인터에 기록합니다. 결과적으로 크래시를 포함하여 정의되지 않은 동작이 발생합니다. 이 행둥의 첫 번째 인스턴스가 충돌하지 않는 것이 행운입니다 (좋든 나쁘 든, 어떻게 보느냐에 따라 다름).

old_dir에 메모리를 할당해야합니다. 이 작업을 수행하는 가장 쉬운 방법은 스택

FilesStruct old_dir; 
memset(&old_dir,0,sizeof(old_dir)); 

에 그것을 선언하는 것입니다 또는 동적 (더 이상 개체를 필요로 할 때 free를 호출하지하는 확인하는) 힙에 할당 할 수

FilesStruct *old_dir = calloc(1, sizeof(*old_dir); 
/* use old_dir */ 
free(old_dir); 

코드 아래에있는 new_dir에도 동일하게 적용됩니다.

+0

오을 할 수있는 포인터 또는 동적으로 할당 된 메모리가 필요하지 않습니다 . 그래서 내 선언은 포인터 만 선언하지만 기본 구조는 선언하지 않습니다. 따라서, 나는 0으로 memsetting하기 전에 메모리를 할당해야합니까? –

+0

@Noob 네, 맞습니다. – simonc

+0

도와 줘서 고마워요! –

3

old_dirnew_dir도 초기화되지 않으므로 이것은 정의되지 않은 동작입니다. memset를 호출 할 때

FilesStruct old_dir; 
//... 
FilesStruct new_dir; 

와 주소를 얻기 위해 & 연산자를 사용 : 하나 개의 솔루션 스택에 두 변수를 할당하는 것입니다

memset(&old_dir,0,sizeof(FilesStruct)); 
3
FilesStruct *old_dir; 

이것은 FilesStruct 포인터를 정의합니다. 초기화되지 않았으므로 실제로 FilesStruct의 저장소를 가리 키지는 않습니다.

memset(old_dir,0,sizeof(FilesStruct)); 

old_dir이 가리키는 포인터가 모두 0이되도록 memset에 알려주지 만, 포인터가 초기화되지 않았기 때문에 정의되지 않은 동작이 발생합니다.

포인터를 저장할 공간이 필요합니다. 귀하의 경우에는

FilesStruct *old_dir = malloc(sizeof(FilesStruct)); 

당신은 정말 아주 틀린 것을 가지고 생각, 당신은 내가 initialiser로 memset 함수를 사용하고자했다

FilesStruct old_dir; 
memset(&old_dir,0,sizeof(FilesStruct)); 
old_dir.x = 3; 
old_dir.text = 'c'; 
printf("old dir: %d,%c\n",old_dir.x,old_dir.text); 
관련 문제