2017-02-28 7 views
-1

내 플렉스 파일의 정의 부분에서는, 전역 포인터을 선언하는 문제가있다, 그럼 내가 빨리 내 주요의 시작에서 그것을 malloc하지만 내 프로그램이 yylex()으로 실행될 때,포인터의 값은 NULL으로 설정됩니다.글로벌 포인터는 yylex 호출 한 후 NULL로 설정()

이 포인터는 내 프로그램 전체에 걸쳐 (this is struct Modele * model)이 포인터가 필요합니다. 기본적으로 파일의 모든 결과를 저장하는 구조체이므로 실제로 없으면 할 수 없습니다. main()yylex() 모두에서 올바르게 작동하는 구조체에 대한 포인터.

실행시 프로그램이 segfault로 실행되어 주소 0x4에 쓰려고 시도합니다. valgrind에서 프로그램을 실행하고 model 값을 인쇄하면 메모리가 올바르게 할당되었음을 알게되었지만 yylex가 호출되자 마자 model의 값은 NULL (인쇄 된 (nil))이었습니다. 여기에 머리글을 사용하지는 않지만 모든 구조체를 저장하고 글로벌 범위 변수를 선언했지만 성공하지는 못했습니다.

내 질문은 : 내가 그와 같은 행동에 직면하는 것이 잘못 되었습니까? 그리고 일반적으로이 문제가 발생하지 않는 가장 좋은 방법은 무엇입니까? 나는 전역 스코프 포인터를 사용했는지 확신 할 수 없다. 그래서 이것, 또는 아마도 flex-lex 특정 문제 일 수있다.

코드의 조각, 나는 그것을 더 붙여 넣을 수 있습니다 문제의 출처를 잡아 충분하지 않은 경우
%{ 

#include <stdlib.h> 
#include <stdio.h> 
//some more includes and #defines 

typedef struct Doc { 
    int classe; 
    uint32_t * words; 
    int current_index; 
    int current_size; 
} doc; 

typedef struct Modele { 
    int nb_classes; 
    int nb_docs; 
    int nb_docs_base; 
    int nb_docs_test; 
    int base_or_test; 
    int voc_size; 
    int M_test_size; 
    liste ** M_theta; 
    row_info * M_calc; 
    doc * M_test; 
} modele; 
//some more typedefs 

modele * model; //    <--- this is the pointer i talk about 

//some more functions bodies ..... 
%} 

couple_entiers  [0-9]+:[0-9]+ 
// ....... 
%% 

{couple_entiers} { model->nb_docs ++} 
//..... 

%% 

int main (int argc, char ** argv) 
{ 
    // ..... 
    modele * model = malloc(sizeof model); // <---- here is the malloc 
    model->nb_classes = 0; 
    model->nb_docs = 0; 
    model->nb_docs_base = 0; 
    model->nb_docs_test = 0; 
    model->voc_size = 0; 
    model->M_test = malloc (TAB_SIZE * sizeof(doc)); 
    //.... 
    if ((yyin = fopen(argv[1],"r")) == NULL){ 
      printf("Impossible d'ouvrir %s !\n",argv[1]); 
      exit(0);  
     } 

     yylex(); 

, 나는 단지를 선택하고 싶었 : 여기

내 코드의 샘플입니다 관련 부분.

+0

'YY_DECL' 매크로를 정의하여'yylex'의 프로토 타입을 변경할 수 있습니다. 따라서 많은 사람들처럼 전역 변수를 싫어하면 전역 변수에 의존 할 필요가 없습니다. – rici

답변

2

내 질문은 : 내가 그런 행동에 직면하는 것이 잘못 되었습니까?

파일 범위 변수를 설정하지 않았습니다. main() 함수는 로컬 같은 이름 및 유형의 변수를 선언하고 초기화합니다. 로컬 선언은 스코프 내에서 파일 범위를 "음영"합니다.

그냥이 변경, 그것을 해결하기 위해 ... 이것에

modele * model = malloc(sizeof model); 

... : 당신이 유형의 변수 이름 앞에하지 않는 경우

model = malloc(sizeof model); 

다음에 언급하는 다른 곳에서 선언 된 변수 (이 경우 파일 범위).

+2

추가 : OP는 항상'-Wshadow' (gcc, 다른 컴파일러는 다른 옵션을 사용할 수도 있음)를 포함하는 권장 경고를 활성화해야합니다. – Olaf

+0

빌어 먹을 권리, 어리석은 실수는 실제로 나에게 약간의 시간을 들여 주었다 .... 감사합니다. –