2016-08-30 4 views
1

그래서 개인적으로 사용하기 위해 소수의 C 라이브러리를 작성해 왔고 최신 라이브러리까지 확장되었습니다.이 라이브러리에는 문자열 기능 만 포함되어 있습니다. 아마도 질문 제목으로 말할 수 있듯이 SIGSEGV 신호가 나타납니다. 문제는 이것입니다. 제 연구에 따르면 모든 SIGSEGV 오류의 약 99 %가 스택 오버플로 때문인 것으로 나타났습니다. 그 자체는 잘못된 재귀로 인해 발생하지만, 알다시피 재귀를 사용하지는 않습니다. 게다가 발생하는 몇 가지 이상한 문제가 있습니다. 하나 들어, printf 많은 펑키 동작을 전시하고있다. GDB는 printf 호출을 만나지 만 나중에 실제로는 몇 줄의 코드가 실행될 때까지는 실행하지 않습니다. 마찬가지로, 내 printf 문장 중 하나가 어떻게 든 부숴지고, 일부만 호출되고, 다른 부분은 분명히 잘려나 간다. 여기 GCC 기반 SIGSEGV 오류?

"firstIndexOf"기능 (첫 번째 발견 ... 나는 이름이 충돌하는 한 지점에서 원인이 될 수 있으며, 약간의 바다로 갈 수 있습니다 의심 때문에 몇 가지 물건이 재미있는 이름, 키 코드 조각입니다

int firstIndexOfFUNCTION(char thisChar, char* inThisString) 
{ 
     int lengthABC = strlen(inThisString); 
     printf("\nLength of %s is %d",inThisString,lengthABC); 
     int thisFunctionsIndex; 
     for (thisFunctionsIndex=0;thisFunctionsIndex<lengthABC;thisFunctionsIndex++) 
     { 
       printf("\n%dth iteration:\n-char 1 is %c\n-char2 is %c",thisFunctionsIndex,inThisString[thisFunctionsIndex],thisChar); 
       if (inThisString[thisFunctionsIndex] == thisChar) 
       { 
         printf("\nMatch found on iteration %d!",thisFunctionsIndex); 
         return thisFunctionsIndex; 
       } 
     } 
     printf("\nNo matches detected..."); 
     return -3; 
} 

은 "string_functions_test"기능 (단지 라인 (62)의 다른 기능들)을 테스트하기위한 것 함수 :

문자열, 즉 문자의 상기 경우 문자열)에서 문자의 인덱스는, 31 행에서 발견
int string_functions_test() 
{ 
     printf("PROGRAM INITIALIZED!\n\n"); 
     char* sft_string; 
     int sft_index; 

     sft_string = malloc(sizeof(char)*100); 
     sft_string = "B um sbm. Sbm B bm."; 

     printf("2nd BREAKPOINT"); 

     sft_index = firstIndexOfFUNCTION('B',sft_string); 

     sft_string[sft_index] = 'I'; 

     return 0; 
} 
좋은 똑똑한,210

그리고 마지막으로 '메인 라인에서 107 :

(gdb) b 105 
Breakpoint 1 at 0x400970: file string_functions.c, line 105. 
(gdb) run 
Starting program: /home/user/Development/projects/c/string_functions/source/c/a.out 

Breakpoint 1, main (argc=1, argv=0x7fffffffde98) at string_functions.c:109 
109    string_functions_test(); 
(gdb) step 
string_functions_test() at string_functions.c:64 
64    printf("PROGRAM INITIALIZED!\n\n"); 
(gdb) next 
PROGRAM INITIALIZED! 

68    sft_string = malloc(sizeof(char)*100); 
(gdb) next 
69    sft_string = "B um sbm. Sbm B bm."; 
(gdb) next 
71    printf("2nd BREAKPOINT"); 
(gdb) next 
73    sft_index = firstIndexOfFUNCTION('B',sft_string); 
(gdb) step 
firstIndexOfFUNCTION (thisChar=66 'B', inThisString=0x400ab9 "B um sbm. Sbm B bm.") at string_functions.c:33 
33    int lengthABC = strlen(inThisString); 
(gdb) next 
34    printf("\nLength of %s is %d",inThisString,lengthABC); 
(gdb) next 
2nd BREAKPOINT 
36    for (thisFunctionsIndex=0;thisFunctionsIndex<lengthABC;thisFunctionsIndex++) 
(gdb) next 
38      printf("\n%dth iteration:\n-char 1 is %c\n-char2 is %c",thisFunctionsIndex,inThisString[thisFunctionsIndex],thisChar); 
(gdb) next 
Length of B um sbm. Sbm B bm. is 19 
0th iteration: 
-char 1 is B 
39      if (inThisString[thisFunctionsIndex] == thisChar) 
(gdb) next 
41        printf("\nMatch found on iteration %d!",thisFunctionsIndex); 
(gdb) next 
-char2 is B 
42        return thisFunctionsIndex; 
(gdb) next 
47  } 
(gdb) next 
string_functions_test() at string_functions.c:75 
75    sft_string[sft_index] = 'I'; 
(gdb) next 

Program received signal SIGSEGV, Segmentation fault. 
0x0000000000400883 in string_functions_test() at string_functions.c:75 
75    sft_string[sft_index] = 'I'; 
(gdb) next 

Program terminated with signal SIGSEGV, Segmentation fault. 
The program no longer exists. 
(gdb) quit 

당신은 것을 알 수 있습니다 : 여기

int main(int argc, char* argv[]) 
{ 
     string_functions_test(); 
     return 0; 
} 

내 코드의 스텝을 통해 대한 GDB 출력은 "2nd Breakpoint"를 인쇄하는 printf가 호출 된 다음 결과가 표시되기 전에 프로그램이 다른 함수로 단계별로 진행됩니다. 나는 이것이 gcc 컴파일러가 cpu 최적화 기능을 수행하도록 의도 한 부분에 약간의 엉뚱한 행동을한다고 가정하고있다. 그러나 그것은 당연히 나를 괴롭 히고있다. 마찬가지로, 내 for 루프의 printf는 첫 번째 형식화 된 문자 뒤에 분리됩니다. 이 두 가지로 정확히 무슨 일이 일어나는지 탐지하기가 어렵습니다. 비슷한 행동을 경험 한 사람이 있습니까? 먼저 malloc에서 반환 된 것을 포인터 sft_string을 가리키는

#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
+2

"연구 결과에 따르면 모든 SIGSEGV 오류의 약 99 %가 스택 오버 플로우로 인한 것입니다."- 연구 결과가 잘못되었습니다. 'printf()'는 예측할 수 없습니다. 왜냐하면 개행이 거의 끝나지 않아 플러시되지 않기 때문입니다. –

+1

약 20 초가 걸렸습니다. :-)'sft_string = malloc (sizeof (char) * 100); sft_string = "Bum sbm. Sbm B bm."; ' – 2501

+0

@PaulGriffiths 실제 백분율은 무엇입니까? – 2501

답변

2

: 그것은, 내가 포함하고 중요한 경우

. 다음 줄에서는 리터럴 문자열을 가리 킵니다. 그것을 복사해야합니다. 리터럴은 소스 코드에 내장되어 있으며 실행 중에 변경할 수 없습니다. 그렇지 않으면 세그먼트 오류가 발생합니다. 즉, 코드가있는 메모리 영역이 변경되고 있음을 의미합니다. strcpy을 사용하십시오.

+0

문자열 리터럴의 할당이 할당 된 메모리는 자체적으로 문제가됩니다. –