2009-08-18 6 views
2

이 코드는 정상적으로 컴파일되지만 실행 중 세그먼트 오류 오류가 발생합니다. 왜 그 이유를 알 수 있습니까?C에서 간단한 문자열 런타임 오류가 발생 했습니까?

#include <stdio.h> 
#include <string.h> 
#include <math.h> 

int main() { 
    const char s2[] = "asdfasdf"; 
    char* s1; 

    strcpy(s1, s2); 
    printf("%s", s1); 

    return 0; 
} 
+0

정상적으로 컴파일하는 코드는 안정적인 프로그램을 보장하지 않습니다.컴파일러는 * 당신을 위해 * 검사를 할 것입니다. 적어도 C 언어가 아닌 모든 가능한 안전하지 않은 프로그램을 제거 할 수있는 방법은 없습니다. 다른 많은 언어는 훨씬 더 보호되어 있지만, 대부분은 당신이 임의의 메모리에 접근하도록하지 않습니다. 방법 C가 않습니다. – quark

답변

13

단일 포인터, s1을위한 공간을 할당 아닌 바이트 s1에 의해 지적했다.

s1 = (char *)malloc(strlen(s2) + 1); 
strcpy(s1, s2); 

당신이 문자의 수보다 (malloc에 대한 호출에 +1) 메모리를 하나 더 바이트를 할당 할 필요가 유의 사항 :

해결책은 동적 s1 메모리를 할당하는 것입니다 s2 끝에 암시적인 NULL 바이트가 있기 때문입니다.

자세한 내용은 C Memory Management (Stack Overflow)을 참조하십시오.

+1

s2는 정적으로 할당 된 배열이기 때문에 sizeof()를 사용하여 nul-terminator를 포함한 크기를 얻을 수 있습니다. 물론 strlen() + 1은 일반적인 경우에 맞습니다. –

+1

다음은 답을 혼란스럽게 만들고 싶지 않은 몇 가지 팁입니다 : 1) _Do_ 's1! = NULL'을 확인하고 2) _do_ 즉시 반환하지 않는 코드에서's1'에'free'를 호출하십시오 . –

+0

또한, 포인터 's1'은 초기화되지 않았기 때문에 어디에도 지정하지 않습니다. 초기화 될 때 문자열을 저장할 충분한 공간을 가리켜 야합니다. 공간은'malloc()'에서 올 수 있습니다; 그것은 다른 곳에서 올 수도 있습니다. –

4

s1에 메모리를 할당하지 않았습니다. 당신은 s1에 대한 포인터를 가지고 있지만 s2의 값을 복사하기 위해 strcpy에 할당 된 메모리는 없다.

char *s1 = malloc(strlen(s2) + 1); 

strcpy(s1, s2); 
+2

malloc 호출에 off-by-one 오류가 있습니다. –

+0

그리고'strcpy'는 2 개의 인자만을 취합니다. 어쩌면 당신은'strncpy'에 대해 생각하고있을 것입니다. –

+0

고맙다 Andrew, 지금 고쳐 줘. 아, 네 말이 맞아. 숀, 수정하도록 수정합니다. – nathan

1

대상을 할당해야합니다 (using namespace std;은 C가 아니지만 C++이며 나머지 코드는 C입니다).

2

문제는 s1에 연결된 메모리가 없다는 것입니다. strcpymalloc()을 호출하지 않습니다.

당신은 하나가 할 수있는 :

char s1[10];

또는

char *s1 = malloc(10);

+2

그러나 strdup는이를 지원하는 시스템에서 수행합니다. :-) –

3

당신은 S1에 메모리를 할당하지 않았습니다. 그것은 아무것도 가리 키지 않습니다.

char* s1 = malloc(sizeof(s2)); 
strcpy(s1, s2); 
printf("%s", s1); 
free(s1); 
+2

s2가 배열이기 때문에 sizeof (s2)가 작동합니다. 포인터 인 경우 strlen (s2) +1이 필요합니다. – AProgrammer

0

포인터 s1에 메모리를 할당해야합니다. 그렇게하지 않으면 알려지지 않은 곳을 가리키고 세그멘테이션 오류가 발생합니다. 올바른 코드는 다음과 같아야합니다.

#include <stdio.h> 
#include <string.h> 
#include <math.h> 

int main() { 
    const char s2[] = "asdfasdf"; 
    char* s1 = malloc(21 * sizeof(s2[0])); 
    strcpy(s1,s2); 
    printf("%s",s1); 
    return 0; 
} 
+1

sizeof (char) == 1이 표준에서 보장되므로 sizeof (char)는 필요하지 않습니다. C가 있기 때문에 (char *) 형변환은 필요 없으며, void 포인터는 암시 적으로 다른 종류의 포인터로 변환 될 수 있습니다. –

+0

@Tyler McHenry 죄송합니다. 학교에서 필요하다는 것을 알았습니다. 어쨌든 sizeof 부분에 대해서는 필자가 다른 유형의 코드로 변경 한 경우에 있어야한다고 생각합니다. – Guilherme

+1

그럼'sizeof (s2 [0])'또는'sizeof (* s2)'로 만드십시오. –

2

s1의 공간을 할당해야합니다. 당신이 간단한 방법은 기존의 문자열을위한 공간을 할당 할 새로운 포인터에 복사하는 경우 다른 작동 게시 한 어떤 사람은 잘하지만, 다음과 같이에서는 StrDup 사용

#include <stdio.h> 
#include <string.h> 
#include <math.h> 

using namespace std; 

int main() { 
    const char s2[] = "asdfasdf"; 
    char* s1; 

    s1 = strdup(s2); 
    printf("%s", s1); 

    return 0; 
} 

누군가가에서는 StrDup 앞서 언급, 그것은 그것을 사용하는 방법이 될 것입니다. 대부분의 시스템은 표준 라이브러리에 있기 때문에 지원해야합니다. 그러나 분명히 어떤 사람들은 그렇지 않습니다. 따라서 오류를 반환하는 경우 이미 언급 한 방법을 사용하여 직접 작성하거나 이미 언급 한 방법을 사용하십시오.)

2

아직이 문제를 해결하기 위해 strdup (String Duplicate)의 잠재력을 지적한 사람은 없습니다.

#include <stdio.h> 
#include <string.h> 
#include <math.h> 

using namespace std; 

int main() { 
    const char s2[] = "asdfasdf"; 
    char* s1; 

    s1 = strdup(s2); // Allocates memory, must be freed later. 
    printf("%s", s1); 

    free(s1);   // Allocated in strdup, 2 lines above 
    return 0; 
} 
관련 문제