2016-09-18 4 views
0

여기 내 어휘 분석기에 대한 코드의 도우미 함수로 사용 작은 람다 함수의는 strtod 사용 후 발생 Token하는 속성을 가진 클래스입니다 value 유형이 void이고, line 유형이 int이고, type이 사용자 지정 enum token_type입니다. 첫 번째 줄에서는 새 값을 생성자에 전달하여 값에 대한 null 포인터 (여전히 생성해야하므로), 열거 형 값 token_type (이 토큰이 해당 유형이므로 number) 및 현재 행 우리는 람다에서 체포했습니다.이상한 일들이 표준 :

iconst char* 유형의 포인터로, 현재 검사중인 문자를 가리 킵니다. 이 람다 함수를 호출하면 프린터 할 수있는 문자를 가리킬 것입니다.

printf은 디버깅 용도로 사용됩니다.

그래서 내가하려는 것은 다음과 같습니다. Tokennumber; 현재 위치에서 번호를 만들 수 있다면 strtod에게 문의하십시오. strtod이 0이 아닌 값을 반환했는지 확인하십시오.이 경우 값을 새 Token에 저장하고, 우리가 가리키는 문자의 위치를 ​​숫자 바로 뒤의 문자로 옮기고 Token을 반환합니다.

strtod이 대신 0 값을 반환 한 경우 실제 0을 찾았거나 대신 숫자를 작성할 수 없으므로 0을 나타내는 경우 다시 검사해야합니다. 그래서 숫자 이후의 포인터가 현재 위치와 같은 문자를 가리키는 지 확인합니다. 사실이라면 strtok은 그 포인터를 앞으로 나아 가지 않았기 때문에 숫자가 전혀 발견되지 않았 음을 의미합니다. 할당 된 값을 반환하고 null 포인터를 보내 신호). 그렇지 않으면 0이 발견되어 저장하고 사전에 저장하고 반환합니다.

문제는 말 그대로 segfault의 오류가있다 내가 after_number을 복종하려고 모든 시간 : 즉, 내가 buildnumber를 호출하는 경우가 "Advancing position"를 인쇄 한 후 "111" 같은 문자열에 i 점, 나는 세그먼트 폴트를 얻을 때. 그리고 i"+0.0" 또는 "abc()"과 같은 문자열을 가리킬 때 전화하면 "Value was 0, comparing position to after number"을 인쇄 한 후 segfault가 표시됩니다.

왜 그렇습니까? after_number이 가리키는 포인터는 어떻게됩니까? 내가 도대체 ​​뭘 잘못하고있는 겁니까?

+1

'i == * after_number'는 정의되지 않은 동작을 발생시킵니다. null 포인터를 dereferncing –

+0

이것은 작지 않다. –

+0

@nm 글쎄, 만약 당신이'printf' 라인을 꺼내면 너무 길지 않다. 그리고 "If it's를"0으로 비교 "한 후에 압축 할 수도있다. 하나는'&&'를 사용했습니다. – user6245072

답변

6

after_number을 문자 포인터에 대한 포인터로 정의한 다음 실제로 유용한 점을 가리 키지 않으면 ,을 직접 사용했습니다.

그 문제는 당신이 기본적으로 실제로 저장 최종 포인터 (당신이 그것을에 저장하는 주소로 nullptr 제공했기 때문에)는, 당신은 가서 그것을 역 참조하려고하지 strtod을 이야기하고 있다는 것입니다 어쨌든 - 여전히 nullptr이 될 것이므로 정의되지 않은 동작이 발생합니다.

올바른 방법은 다음과 같이이해야 할 일 :

char *after_number; 
double *value = new double(std::strtod(i, &after_number)); 

이 실제로 strtod 최종 포인터를 배치 할 수있는에char * 변수를 생성하고, strtod에 그것의 주소를 전달합니다. 종료시, after_number은 숫자 평가를 중단 한 끝 문자에 대한 포인터를 유지합니다. (실제로는 제공된 실제 문자열 끝에 대한 포인터가됩니다. *after_number == '\0'

+0

저는 이런 식으로 사용하라고 맹세했지만 약간의 실수를 던졌고 그것을 해결할 것이라고 생각하는 잘못된 방향으로 전환했습니다. 어쨌든 이제는 효과가 있습니다. – user6245072

관련 문제