2013-11-21 7 views
1

에 있습니다!문자열을 복사 할 때 세그먼트 오류가

아래는 제가 오늘 만든 작은 프로그램입니다. 문자열 테이블을 가져와 테이블을 뒤집지 않고 모든 문자열을 역순으로 변환 한 다음 역순으로 정렬 한 다음 다시 역순으로 정렬하고 마지막으로 전체 테이블을 인쇄합니다.

strcmp를 가리키는 테이블에서 '느린'문자열을 복사 할 수없는 이유를 알아 내려고 노력했지만 정말 성공하지 못했습니다. 이 경우 Segmentation Fault를 수정하는 방법을 찾을 수 있다면 행복 할 것이지만, 아래의 방법을 그대로두고 싶습니다.

도움 주셔서 감사합니다. :)

이 분명 아니었다면 내가 분할 오류가 strcpy를 나타나는지 결정 디버거를 사용하여

편집 ... 계산할 때

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

const int ROZMIAR=4; 
char* nieposortowane[]={"basia", "zosia", "ala", "genowefa"}; 

int porownaj(char* a, char* b) 
{ 
return strcmp(a,b); 
} 

void sortowanie(char** tablica, int N) 
{ 
int zamienione, i; 
char tmp; 

do 
{ 
    zamienione=0; 
    for(i=0;i<N-1;i++) 
     if(porownaj(nieposortowane[i], nieposortowane[i+1])>0) 
     { 

      tmp=**(tablica+i); 
      **(tablica+i)=**(tablica+(i+1)); 
      **(tablica+(i+1))=tmp; 

      zamienione=1; 
     } 
} 
while(zamienione); 
} 

void wypisz(char** tablica, int N) 
{ 
int i=0; 
for(i=0;i<N;i++) 
    printf("%s\n", *(tablica+i)); 
} 

void odwr(char** tablica, int N) 
{ 
int i, ln, c; 
int start, koniec; 
char temp; 

for(i=0;i<N;i++) 
{ 
    ln = strlen(tablica[i]); 
    char slowo[ln]; 
    strcpy(slowo,*(tablica+i)); 
    start=0; 
    koniec=ln-1; 
    for(c=0;c<(ln/2);c++) 
    { 
     temp =slowo[start]; 
     slowo[start]=slowo[koniec]; 
     slowo[koniec]=temp; 
     start++; 
     koniec--; 
    } 
    strcpy(*(tablica+i), slowo); 
} 
} 

int main() 
{ 
printf("Przed sortowaniem: \n"); 
wypisz(nieposortowane, ROZMIAR); 

odwr(nieposortowane, ROZMIAR); 
sortowanie(nieposortowane, ROZMIAR); 
odwr(nieposortowane, ROZMIAR); 

printf("Po sortowaniu babelkowym: \n"); 
wypisz(nieposortowane, ROZMIAR); 

return 0; 
} 
+1

"basia"는 문자열 리터럴입니다. 문자열 리터럴 재 작성 금지. – BLUEPIXY

답변

0

AFAICS, 당신은에있는 문자열을 수정하려고 : 읽기 전용 메모리에 저장

char* nieposortowane[]={"basia", "zosia", "ala", "genowefa"}; 

들이다 문자열 리터럴; 그것들을 바꾸려는 시도는 실패 할 것입니다.

원본 코드로 충돌을 재현했습니다. 이 코드 개정판은 충돌하지 않습니다. 대신 정렬 코드에서 무한 루프가됩니다. 귀하의 코드 부분을 디버깅하지 않았습니다.

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

const int ROZMIAR=4; 
char basia[] = "basia"; 
char zosia[] = "zosia"; 
char ala[] = "ala"; 
char genowefa[] = "genowefa"; 
char* nieposortowane[]={basia, zosia, ala, genowefa}; 

int porownaj(char* a, char* b) 
{ 
return strcmp(a,b); 
} 

void sortowanie(char** tablica, int N) 
{ 
int zamienione, i; 
char tmp; 

do 
{ 
    zamienione=0; 
    for(i=0;i<N-1;i++) 
     if(porownaj(nieposortowane[i], nieposortowane[i+1])>0) 
     { 

      tmp=**(tablica+i); 
      **(tablica+i)=**(tablica+(i+1)); 
      **(tablica+(i+1))=tmp; 

      zamienione=1; 
     } 
} 
while(zamienione); 
} 

void wypisz(char** tablica, int N) 
{ 
int i=0; 
for(i=0;i<N;i++) 
    printf("%s\n", *(tablica+i)); 
} 

void odwr(char** tablica, int N) 
{ 
int i, ln, c; 
int start, koniec; 
char temp; 

for(i=0;i<N;i++) 
{ 
    ln = strlen(tablica[i]); 
    char slowo[ln]; 
    strcpy(slowo,*(tablica+i)); 
    start=0; 
    koniec=ln-1; 
    for(c=0;c<(ln/2);c++) 
    { 
     temp =slowo[start]; 
     slowo[start]=slowo[koniec]; 
     slowo[koniec]=temp; 
     start++; 
     koniec--; 
    } 
    strcpy(*(tablica+i), slowo); 
} 
} 

int main() 
{ 
printf("Przed sortowaniem: \n"); 
wypisz(nieposortowane, ROZMIAR); 

odwr(nieposortowane, ROZMIAR); 
wypisz(nieposortowane, ROZMIAR); 

sortowanie(nieposortowane, ROZMIAR); 
wypisz(nieposortowane, ROZMIAR); 
odwr(nieposortowane, ROZMIAR); 
wypisz(nieposortowane, ROZMIAR); 

printf("Po sortowaniu babelkowym: \n"); 
wypisz(nieposortowane, ROZMIAR); 

return 0; 
} 

샘플 출력 :

Przed sortowaniem: 
basia 
zosia 
ala 
genowefa 
aisab 
aisoz 
ala 
afewoneg 

나는 그 후 중단했다,하지만 당신은 문자열이 성공적으로 반전되는 것을 볼 수 있습니다.

좀 더 일반적인 해결책을 찾아야합니다. 필자가 한 것처럼 개별 배열의 이름을 지정하는 것은 작은 고정 세트에는 쉽지만 일반적으로는 아닙니다. 하나의 가능성은 각각의 문자열을 할당 된 공간에 복제하기 위해 strdup()을 사용하는 것입니다 :

enum { SIZE_NPSW = sizeof(nieposortowane)/sizeof(nieposortowane[0] }; 

for (i = 0; i < SIZE_NPSW; i++) 
    nieposortowane[i] = strdup(nieposortowane[i]); 
+0

예! 문제가 해결되었습니다. 전역 선언의 변경으로 인해 버블 정렬 함수를 약간 변경해야했지만 지금은 작동합니다. 고맙습니다 :) – wnerw

2

slowo를 할당, 당신은 strlen의 결과에 1을 추가해야합니다 할당 할 크기 이것은 문자열의 길이가 (strlen에서 반환 됨)에 포함되지 않지만 전체 할당 크기에 포함되어야하는 종료 널 문자를 수용하기위한 것입니다.

+0

그게 문제 였다면 나는 정말로 바보 같았다. ln에 1을 더하여 할당을 고정했지만이 프로그램을 실행해도 분할 오류가 발생했습니다 ... – wnerw

+0

BLUEPIXY가 올바르므로 그 이유는 다음과 같습니다 : [문자열 리터럴] (http://bytes.com/topic/c)에 쓸 수 없습니다./answers/213252-string-string-literal-could-anyone-explain-me)! 추신 : 폴란드어? – paulsm4

+0

예프;) 바르샤바 공과 대학에서 공부하는 폴란드 인. – wnerw