문제

내 코드는 segfaults이고 왜 그런지 모르겠습니다.

 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 디버거 (GDB 디버거는 문제가 숯을 저장하려는 6 행에 C-String)에 있다고 말합니다 (LValue Pointer Deerferencing을 사용하는 경우 같은 문제입니다.) 이것이 그가 말하는 것입니다.

(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

나는 K & R-C Book에서 배우고 있으며 이것은 2.8 장 (제거 함수)의 단순화 된 예입니다. 나는 문제가 어디에 있는지 전혀 모른다.

도움이 되었습니까?

해결책

char*s = "abcde"때문에; Readonly 메모리에서 문자열을 만듭니다. 노력하다

char s[] = "abcde";

편집 : 설명 : char*는 포인터이며 "ABCDE"는 ReadOnly Memory-> Emutable에서 생성됩니다.

char []는 배열이며, 스택에 전적으로 저장되고 메모리에서 초기화되므로 변동성이 있습니다.

다른 팁

당신이 a에 대한 포인터를 정의 할 때 문자열 문자, 그것을 선언하십시오 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 */

동의하지 않고 정교화하기 위해 : 컴파일러가이를 허용하면 어떻게 될지 고려하십시오. 당신은 쓸 수 있습니다 :

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

컴파일러가 두 리터럴이 동일하다는 것을 인식하고 재사용하지만 라인 3도 허용하는 경우 출력이 다음과 같습니다.

xbcde
xbcde

아마도 당신이 원하는 것이 아닐 것입니다. 두 리터럴이 프로그램의 널리 분리 된 부분에 있다면 이것은 특히 신비 롭습니다.

시험해보세요 :

#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;
}

내 추측은 유형을 숯 배열로 정의하는 매개 변수 정의입니다. 당신이 숯으로 포인터를 전달하는 동안

첫 번째 줄을 이것으로 바꿀 수 있습니다.

 void overwrite(char *str, char x) {

숯 어레이와 숯 포인터는 의미 적으로 동일하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top