2009-09-10 9 views
3

내 코드 segfaults 및 이유를 모르겠습니다. (나는 좌변 포인터 역 참조 사용하는 경우이 같은 문제입니다.)C 문자열로 작성

1 #include <stdio.h> 
2 
3 void overwrite(char str[], char x) { 
4 int i; 
5 for (i = 0; str[i] != '\0'; i++) 
6  str[i] = x; 
7 } 
8 
9 int main(void) { 
10 char *s = "abcde"; 
11 char x = 'X'; 
12 overwrite(s, x); 
13 printf("%s\n", s); 
14 return 0; 
15 } 

gdb를 디버거가 나에게 말한다는, 그 문제는 C - 문자열로, 나는 문자를 저장할 라인 6에이 무슨이다 그는 말한다 : 나는 K & RC 책에서 배우고이 장 2.8 (제거 기능)에서 예를 단순화

(gdb) run 
Starting program: /tmp/x/x 

Breakpoint 1, overwrite (str=0x8048500 "abcde", x=88 'X') at x.c:5 
5   for (i = 0; str[i] != '\0'; i++) 
(gdb) s 
6   str[i] = x; 
(gdb) 

Program received signal SIGSEGV, Segmentation fault. 
0x080483e3 in overwrite (str=0x8048500 "abcde", x=88 'X') at x.c:6 
6   str[i] = x; 
(gdb) q 

. 나는 문제가 어디 있는지 전혀 모른다.

답변

17

char * s = "abcde"이기 때문에; 읽기 전용 메모리에 문자열을 만듭니다. 시도해주세요 : 설명 : char *는 포인터이며 "abcde"는 읽기 전용 메모리 -> 불변으로 생성됩니다.

CHAR는 []를

-2

제 추측는 문자의 배열과 형태를 정의하는 파라미터의 정의는 가변이며, 전체적으로 스택에 저장하고, 메모리 어레이에서 초기화된다. 당신이 문자

에 대한 포인터를 전달하는 동안이에 첫 번째 줄을 변경 시도 할 수 :

void overwrite(char *str, char x) { 

문자 배열 및 문자 포인터가 의미 상 동일하지 않습니다.

+0

'숯 STR 함수 인수로 동일하다. – sepp2k

+0

틀린거야,'char str []'는 매개 변수 목록에서 사용될 때'char *'로 쇠퇴한다. – avakar

+0

괜찮 았어.하지만 ... 나는 맞다. 어떤 경우에 그것이 다른 것인지 자세히 설명해 주시겠습니까? – Toad

2

문자열 리터럴에 대한 포인터를 정의 할 때 const char *으로 선언하십시오.

const char *s = "abcde"; 

그런 식으로 문자열을 overwrite() 함수로 보내려고하면 컴파일러에서 불평합니다.

const char *s = "abcde"; 
char t[] = "fghij"; 
char x = 'X'; 

overwrite(s, x); /* oops */ 
overwrite(t, x); /* ok */ 
1

동의하지는 않지만 정교하게 설명합니다. 컴파일러에서 허용하는 경우 어떻게 될지 고려하십시오. 당신은 쓸 수 :

char *s1="abcde"; 
char *s2="abcde"; 
s1[0]='x'; 
puts(s1); 
puts(s2); 

를 컴파일러가 두 리터럴이 동일한 그들을 재 - 사용하지만 다음도 3 호선을 수 있다는 인식하면, 당신의 출력은 다음과 같습니다

xbcde 
xbcde 

아마 어느 네가 원하는 것이 아니라. 이것은 두 개의 리터럴이 프로그램에서 광범위하게 분리 된 부분에 있다면 특히 신비 할 것입니다.

+0

이것은 .Net 문자열이 불변 인 이유입니다. 문자열은 "string interning"이라는 문자열을 통해 재사용됩니다. –

+0

@Tom Ritter - 그렇습니다 .Net은 C와 완전히 다른 목표를 가진 전혀 다른 플랫폼입니다. –

-1

해보세요 [] '과'숯 *의 str`

#include <iostream> 
#include <cstring> 

using namespace std; 

void overwrite(char[], char); 

int main(void) 
{ 
     char *s = strdup("abcde"); 
     char X = 'X'; 
     overwrite(s, X); 
     cout << s << endl; 

     if(s!=NULL) 
       delete [] s; 

     return 0; 
} 

void overwrite(char str[], char x) 
{ 
     for(int i=0; str[i]!='\0'; i++) 
       str[i] = x; 
} 
+0

질문은 C ...로 태그 지정되며, NULL이 있는지 확인하려는 경우에는 잘못된 포인터를 사용하는 대신 strdup() 호출을 사용하십시오. – pmg

+0

또한 strdup는 malloc()을 호출합니다. delete []를 호출하는 것은 잘못되었습니다. – Nicholaz