Segmentation fault...

I have a segmentation fault again...
It's a little wierd...
This is some piece of code I'm working on:

[code]
#include
#include

char look; // { Lookahead Character }
FILE *ifile; // input stream
FILE *ofile; // output stream
char **KWlist;

//{--------------------------------------------------------------}
//{ Read New Character From Input Stream }

void GetChar(){
look = fgetc(ifile);
}

//{--------------------------------------------------------------}
//{ Report Error}

void Abort(char* s){
printf("
Error %s.", s);
abort();
}

void Expected(char* s){
printf("Error: %s Expected
", s);
abort();
}

//{--------------------------------------------------------------}
//{ Match a Specific Input Character }

void match(char x){
if(look == x)
GetChar();
else{
char* c = "
";
c[0] = x;
Expected(c);
}
}

//{--------------------------------------------------------------}
//{ Recognicion funcs }
char upcase(char c){
if((c >= 'a') & (c <= 'z'))
c += 'A' - 'a';
return c;
}

int IsAlpha(char c){
c = upcase(c);
return ((c >= 'A') & (c <= 'Z'));
}

int IsDigit(char c){
return ((c >= '0') & (c <= '9'));
}

int IsOp(char c){
return (c == '+') | (c == '-') | (c == '*') | (c == '/') | (c == '<') | (c == '>') | (c == ':') | (c == '=') | (c == '!');
}

int IsAlNum(char c){
return IsAlpha(c) | IsDigit(c);
}

int IsWhite(char c){
return (c == ' ') | (c == ' ') | (c == '
');
}


//{--------------------------------------------------------------}
//{ Get an Identifier }

void skipWhite(){
while(IsWhite(look))
GetChar();
}

void Fin(){
if(look == '
') GetChar();
if(look == '
') GetChar();
}

int Lookup(char ** list, char* s, int n){
//++n;
while(n--)
if(list[n][0] == s[0])
if(strcmp(list[n], s) == 0)
return 1;
return 0;
}


char* getName(){
char *c, *p;
if ((c=(char *) malloc(9))==NULL) return NULL;
p = c;
if(!IsAlpha(upcase(look))) Expected("Name");

while(IsAlNum(look)){
*p = upcase(look);
++p;
GetChar();
}
*p = 0;
skipWhite();
return c;
}

char* getNum(){
char *c, *p;
if ((c=(char *) malloc(17))==NULL) return NULL;
p = c;
if(!IsDigit(look)) Expected("Integer");
while(IsDigit(look)){
*p = upcase(look);
++p;
GetChar();
}
*p = 0;
skipWhite();
return c;
}

char* getOp(){
char *c, *p;
if ((c=(char *) malloc(4))==NULL) return NULL;
p = c;
if(!IsOp(look)) Expected("Integer");
while(IsOp(look)){
*p = upcase(look);
++p;
GetChar();
}
*p = 0;
skipWhite();
return c;
}

char* scan(){ //remember to free!!
skipWhite();
char *c;
while(look == '
')
Fin();

if(IsAlpha(look))
c = getName();
else if(IsDigit(look))
c = getNum();
else if(IsOp(look))
c = getOp();
else {
if ((c=(char *) malloc(2))==NULL) return NULL;
*c = look;
++c;
*c = 0;
--c;
GetChar();
}
return c;
}


//{--------------------------------------------------------------}
//{ Initialize }

void init(){
ifile = stdin; //fopen("test.q", "r");
ofile = stdout;
GetChar();

if ((KWlist=(char **) malloc(6))==NULL) Abort("malloc error");
KWlist[0] = "IF";
KWlist[1] = "ELSE";
KWlist[2] = "END";
KWlist[3] = "ENDIF";
KWlist[4] = "1234";
}


//{--------------------------------------------------------------}
//{ Main Program }

int main(){
init();

char* c;
//scanf("%s",c); //this line works
c = scan(); //but this doesn't
printf("%s
", c);
printf("%d
", Lookup(KWlist, c, 4)); //if I put a three here it works but not if it's a four and scan() is used.

free(c);
free(KWlist);

return 0;
}
[/code]

Read the comments in main to understand the prob...
The problem should be with scan() but I can't see why.

It only occures when the third parameter in Lookup is 4 and scan() is used. When the parameters is lower, or scanf() is used it works.

Happy coding wishes
the one and only
[b]Niklas Ulvinge[/b] [white]aka [b]IDK[/b][/white]
«13

Comments

  • You are not using pointers correctly. You declared char*, so you must allocate memory to it before use. Or not declare it as a pointer at all.
    [code]
    char* c = new char; //c++
    char* c = (char*)malloc(sizeof(char) * 1); //c
    char c; //another option
    [/code]

    Hope that helps,
    Mortissus

    : I have a segmentation fault again...
    : It's a little wierd...
    : This is some piece of code I'm working on:
    :
    : [code]
    : #include
    : #include
    :
    : char look; // { Lookahead Character }
    : FILE *ifile; // input stream
    : FILE *ofile; // output stream
    : char **KWlist;
    :
    : //{--------------------------------------------------------------}
    : //{ Read New Character From Input Stream }
    :
    : void GetChar(){
    : look = fgetc(ifile);
    : }
    :
    : //{--------------------------------------------------------------}
    : //{ Report Error}
    :
    : void Abort(char* s){
    : printf("
    Error %s.", s);
    : abort();
    : }
    :
    : void Expected(char* s){
    : printf("Error: %s Expected
    ", s);
    : abort();
    : }
    :
    : //{--------------------------------------------------------------}
    : //{ Match a Specific Input Character }
    :
    : void match(char x){
    : if(look == x)
    : GetChar();
    : else{
    : char* c = "
    ";
    : c[0] = x;
    : Expected(c);
    : }
    : }
    :
    : //{--------------------------------------------------------------}
    : //{ Recognicion funcs }
    : char upcase(char c){
    : if((c >= 'a') & (c <= 'z'))
    : c += 'A' - 'a';
    : return c;
    : }
    :
    : int IsAlpha(char c){
    : c = upcase(c);
    : return ((c >= 'A') & (c <= 'Z'));
    : }
    :
    : int IsDigit(char c){
    : return ((c >= '0') & (c <= '9'));
    : }
    :
    : int IsOp(char c){
    : return (c == '+') | (c == '-') | (c == '*') | (c == '/') | (c == '<') | (c == '>') | (c == ':') | (c == '=') | (c == '!');
    : }
    :
    : int IsAlNum(char c){
    : return IsAlpha(c) | IsDigit(c);
    : }
    :
    : int IsWhite(char c){
    : return (c == ' ') | (c == ' ') | (c == '
    ');
    : }
    :
    :
    : //{--------------------------------------------------------------}
    : //{ Get an Identifier }
    :
    : void skipWhite(){
    : while(IsWhite(look))
    : GetChar();
    : }
    :
    : void Fin(){
    : if(look == '
    ') GetChar();
    : if(look == '
    ') GetChar();
    : }
    :
    : int Lookup(char ** list, char* s, int n){
    : //++n;
    : while(n--)
    : if(list[n][0] == s[0])
    : if(strcmp(list[n], s) == 0)
    : return 1;
    : return 0;
    : }
    :
    :
    : char* getName(){
    : char *c, *p;
    : if ((c=(char *) malloc(9))==NULL) return NULL;
    : p = c;
    : if(!IsAlpha(upcase(look))) Expected("Name");
    :
    : while(IsAlNum(look)){
    : *p = upcase(look);
    : ++p;
    : GetChar();
    : }
    : *p = 0;
    : skipWhite();
    : return c;
    : }
    :
    : char* getNum(){
    : char *c, *p;
    : if ((c=(char *) malloc(17))==NULL) return NULL;
    : p = c;
    : if(!IsDigit(look)) Expected("Integer");
    : while(IsDigit(look)){
    : *p = upcase(look);
    : ++p;
    : GetChar();
    : }
    : *p = 0;
    : skipWhite();
    : return c;
    : }
    :
    : char* getOp(){
    : char *c, *p;
    : if ((c=(char *) malloc(4))==NULL) return NULL;
    : p = c;
    : if(!IsOp(look)) Expected("Integer");
    : while(IsOp(look)){
    : *p = upcase(look);
    : ++p;
    : GetChar();
    : }
    : *p = 0;
    : skipWhite();
    : return c;
    : }
    :
    : char* scan(){ //remember to free!!
    : skipWhite();
    : char *c;
    : while(look == '
    ')
    : Fin();
    :
    : if(IsAlpha(look))
    : c = getName();
    : else if(IsDigit(look))
    : c = getNum();
    : else if(IsOp(look))
    : c = getOp();
    : else {
    : if ((c=(char *) malloc(2))==NULL) return NULL;
    : *c = look;
    : ++c;
    : *c = 0;
    : --c;
    : GetChar();
    : }
    : return c;
    : }
    :
    :
    : //{--------------------------------------------------------------}
    : //{ Initialize }
    :
    : void init(){
    : ifile = stdin; //fopen("test.q", "r");
    : ofile = stdout;
    : GetChar();
    :
    : if ((KWlist=(char **) malloc(6))==NULL) Abort("malloc error");
    : KWlist[0] = "IF";
    : KWlist[1] = "ELSE";
    : KWlist[2] = "END";
    : KWlist[3] = "ENDIF";
    : KWlist[4] = "1234";
    : }
    :
    :
    : //{--------------------------------------------------------------}
    : //{ Main Program }
    :
    : int main(){
    : init();
    :
    : char* c;
    : //scanf("%s",c); //this line works
    : c = scan(); //but this doesn't
    : printf("%s
    ", c);
    : printf("%d
    ", Lookup(KWlist, c, 4)); //if I put a three here it works but not if it's a four and scan() is used.
    :
    : free(c);
    : free(KWlist);
    :
    : return 0;
    : }
    : [/code]
    :
    : Read the comments in main to understand the prob...
    : The problem should be with scan() but I can't see why.
    :
    : It only occures when the third parameter in Lookup is 4 and scan() is used. When the parameters is lower, or scanf() is used it works.
    :
    : Happy coding wishes
    : the one and only
    : [b]Niklas Ulvinge[/b] [white]aka [b]IDK[/b][/white]
    :

  • Some mistakes I have noticed.

    [code]
    #include
    #include

    char look; // { Lookahead Character }
    FILE *ifile; // input stream
    FILE *ofile; // output stream
    char **KWlist;

    //{--------------------------------------------------------------}
    //{ Read New Character From Input Stream }

    void GetChar(){
    look = fgetc(ifile);
    }

    //{--------------------------------------------------------------}
    //{ Report Error}

    void Abort(char* s){
    printf("
    Error %s.", s);
    abort();
    }

    void Expected(char* s){
    printf("Error: %s Expected
    ", s);
    abort();
    }

    //{--------------------------------------------------------------}
    //{ Match a Specific Input Character }

    void match(char x){
    if(look == x)
    GetChar();
    else{
    char* c = "
    ";
    [blue]/*
    You should not declare c this way, because the string "
    " is then considered
    as a string constant and should not be modified. Because you want to modify it
    on the next line, declare c this way instead:

    char c[3]="
    ";

    This line initializes the array whose elements can be modified later.
    */[/blue]
    c[0] = x;
    Expected(c);
    }
    }

    //{--------------------------------------------------------------}
    //{ Recognicion funcs }
    char upcase(char c){
    if((c >= 'a') & (c <= 'z'))
    [blue]/*
    Here it works but you should use && instead because what you want to perform
    is a logical AND (boolean), not a bitwise AND
    */[/blue]
    c += 'A' - 'a';
    return c;
    }

    int IsAlpha(char c){
    c = upcase(c);
    return ((c >= 'A') & (c <= 'Z'));
    [blue]/*Same thing than above*/[/blue]
    }

    int IsDigit(char c){
    return ((c >= '0') & (c <= '9'));
    [blue]/*Same thing than above*/[/blue]
    }

    int IsOp(char c){
    return (c == '+') | (c == '-') | (c == '*') | (c == '/') | (c == '<') | (c == '>') | (c == ':') | (c == '=') | (c == '!');
    [blue]/*It works, but I think that it is preferable to use || to be clearer*/[/blue]
    }

    int IsAlNum(char c){
    return IsAlpha(c) | IsDigit(c);
    [blue]/* || */[/blue]
    }

    int IsWhite(char c){
    return (c == ' ') | (c == ' ') | (c == '
    ');
    [blue]/* || */[/blue]
    }


    //{--------------------------------------------------------------}
    //{ Get an Identifier }

    void skipWhite(){
    while(IsWhite(look))
    GetChar();
    }

    void Fin(){
    if(look == '
    ') GetChar();
    if(look == '
    ') GetChar();
    }

    int Lookup(char ** list, char* s, int n){
    //++n;
    while(n--)
    if(list[n][0] == s[0])
    if(strcmp(list[n], s) == 0)
    return 1;
    return 0;
    }


    char* getName(){
    char *c, *p;
    if ((c=(char *) malloc(9))==NULL) return NULL;
    p = c;
    if(!IsAlpha(upcase(look))) Expected("Name");

    while(IsAlNum(look)){
    *p = upcase(look);
    ++p;
    GetChar();
    }
    *p = 0;
    skipWhite();
    return c;
    }

    char* getNum(){
    char *c, *p;
    if ((c=(char *) malloc(17))==NULL) return NULL;
    p = c;
    if(!IsDigit(look)) Expected("Integer");
    while(IsDigit(look)){
    *p = upcase(look);
    ++p;
    GetChar();
    }
    *p = 0;
    skipWhite();
    return c;
    }

    char* getOp(){
    char *c, *p;
    if ((c=(char *) malloc(4))==NULL) return NULL;
    p = c;
    if(!IsOp(look)) Expected("Integer");
    while(IsOp(look)){
    *p = upcase(look);
    ++p;
    GetChar();
    }
    *p = 0;
    skipWhite();
    return c;
    }

    char* scan(){ //remember to free!!
    skipWhite();
    char *c;
    while(look == '
    ')
    Fin();

    if(IsAlpha(look))
    c = getName();
    else if(IsDigit(look))
    c = getNum();
    else if(IsOp(look))
    c = getOp();
    else {
    if ((c=(char *) malloc(2))==NULL) return NULL;
    *c = look;
    ++c;
    *c = 0;
    --c;
    GetChar();
    }
    return c;
    }


    //{--------------------------------------------------------------}
    //{ Initialize }

    void init(){
    ifile = stdin; //fopen("test.q", "r");
    ofile = stdout;
    GetChar();

    if ((KWlist=(char **) malloc(6))==NULL) Abort("malloc error");
    [blue]/*
    Here you only allocate space for 6 characters, which is not enough to store the 5
    following strings
    */[/blue]
    KWlist[0] = "IF";
    KWlist[1] = "ELSE";
    KWlist[2] = "END";
    KWlist[3] = "ENDIF";
    KWlist[4] = "1234";
    }


    //{--------------------------------------------------------------}
    //{ Main Program }

    int main(){
    init();

    char* c;
    //scanf("%s",c); //this line works
    [blue]/*
    It's amazing the line with scanf works. Normally, you should allocate space to store
    the chars before calling scanf
    */[/blue]
    c = scan(); //but this doesn't
    printf("%s
    ", c);
    printf("%d
    ", Lookup(KWlist, c, 4)); //if I put a three here it works but not if it's a four and scan() is used.

    free(c);
    free(KWlist);

    return 0;
    }
    [/code]

    Steph
  • : You are not using pointers correctly. You declared char*, so you must allocate memory to it before use. Or not declare it as a pointer at all.
    : [code]
    : char* c = new char; //c++
    : char* c = (char*)malloc(sizeof(char) * 1); //c
    : char c; //another option
    : [/code]
    :
    : Hope that helps,
    : Mortissus
    :

    This is C, it doesn't have new
  • [code]
    : //{--------------------------------------------------------------}
    : //{ Initialize }
    :
    : void init(){
    : ifile = stdin; //fopen("test.q", "r");
    : ofile = stdout;
    : GetChar();
    :
    : if ((KWlist=(char **) malloc(6))==NULL) Abort("malloc error");
    : [blue]/*
    : Here you only allocate space for 6 characters, which is not enough to store the 5
    : following strings
    : */[/blue]
    : KWlist[0] = "IF";
    : KWlist[1] = "ELSE";
    : KWlist[2] = "END";
    : KWlist[3] = "ENDIF";
    : KWlist[4] = "1234";
    : }
    :
    [/code]
    I thought I was declaring a an array of pointers to strings.
    Doesn't "Hello" a 'return' a pointer to char.
    Then I move that pointer to an array of 6 bytes.
    The "Hello" is declared on the heap.
    [code]
    :
    : //{--------------------------------------------------------------}
    : //{ Main Program }
    :
    : int main(){
    : init();
    :
    : char* c;
    : //scanf("%s",c); //this line works
    : [blue]/*
    : It's amazing the line with scanf works. Normally, you should allocate space to store
    : the chars before calling scanf
    : */[/blue]
    : c = scan(); //but this doesn't
    : printf("%s
    ", c);
    : printf("%d
    ", Lookup(KWlist, c, 4)); //if I put a three here it works but not if it's a four and scan() is used.
    :
    : free(c);
    : free(KWlist);
    :
    : return 0;
    : }
    : [/code]
  • : [code]
    : : //{--------------------------------------------------------------}
    : : //{ Initialize }
    : :
    : : void init(){
    : : ifile = stdin; //fopen("test.q", "r");
    : : ofile = stdout;
    : : GetChar();
    : :
    : : if ((KWlist=(char **) malloc(6))==NULL) Abort("malloc error");
    : : [blue]/*
    : : Here you only allocate space for 6 characters, which is not enough to store the 5
    : : following strings
    : : */[/blue]
    : : KWlist[0] = "IF";
    : : KWlist[1] = "ELSE";
    : : KWlist[2] = "END";
    : : KWlist[3] = "ENDIF";
    : : KWlist[4] = "1234";
    : : }
    : :
    : [/code]
    : I thought I was declaring a an array of pointers to strings.
    : Doesn't "Hello" a 'return' a pointer to char.
    : Then I move that pointer to an array of 6 bytes.
    : The "Hello" is declared on the heap.
    : [code]
    : :
    : : //{--------------------------------------------------------------}
    : : //{ Main Program }
    : :
    : : int main(){
    : : init();
    : :
    : : char* c;
    : : //scanf("%s",c); //this line works
    : : [blue]/*
    : : It's amazing the line with scanf works. Normally, you should allocate space to store
    : : the chars before calling scanf
    : : */[/blue]
    : : c = scan(); //but this doesn't
    : : printf("%s
    ", c);
    : : printf("%d
    ", Lookup(KWlist, c, 4)); //if I put a three here it works but not if it's a four and scan() is used.
    : :
    : : free(c);
    : : free(KWlist);
    : :
    : : return 0;
    : : }
    : : [/code]
    :
    Yes, sorry, you're right. But remember that if you assign these string constants to the pointers in KWlist, you should not modify these strings later.
    I am working on your code now and I'll try to post something later if I have time.

    Steph
  • : : [code]
    : : : //{--------------------------------------------------------------}
    : : : //{ Initialize }
    : : :
    : : : void init(){
    : : : ifile = stdin; //fopen("test.q", "r");
    : : : ofile = stdout;
    : : : GetChar();
    : : :
    : : : if ((KWlist=(char **) malloc(6))==NULL) Abort("malloc error");
    : : : [blue]/*
    : : : Here you only allocate space for 6 characters, which is not enough to store the 5
    : : : following strings
    : : : */[/blue]
    : : : KWlist[0] = "IF";
    : : : KWlist[1] = "ELSE";
    : : : KWlist[2] = "END";
    : : : KWlist[3] = "ENDIF";
    : : : KWlist[4] = "1234";
    : : : }
    : : :
    : : [/code]
    : : I thought I was declaring a an array of pointers to strings.
    : : Doesn't "Hello" a 'return' a pointer to char.
    : : Then I move that pointer to an array of 6 bytes.
    : : The "Hello" is declared on the heap.
    : : [code]
    : : :
    : : : //{--------------------------------------------------------------}
    : : : //{ Main Program }
    : : :
    : : : int main(){
    : : : init();
    : : :
    : : : char* c;
    : : : //scanf("%s",c); //this line works
    : : : [blue]/*
    : : : It's amazing the line with scanf works. Normally, you should allocate space to store
    : : : the chars before calling scanf
    : : : */[/blue]
    : : : c = scan(); //but this doesn't
    : : : printf("%s
    ", c);
    : : : printf("%d
    ", Lookup(KWlist, c, 4)); //if I put a three here it works but not if it's a four and scan() is used.
    : : :
    : : : free(c);
    : : : free(KWlist);
    : : :
    : : : return 0;
    : : : }
    : : : [/code]
    : :
    : Yes, sorry, you're right. But remember that if you assign these string constants to the pointers in KWlist, you should not modify these strings later.
    : I am working on your code now and I'll try to post something later if I have time.
    :
    : Steph
    :
    Why can't I modify them?
    [code]
    int i = 0;
    i = 2;
    [/code]
    Here i is also declared on the heap, and I can modify it too.
  • : : : [code]
    : : : : //{--------------------------------------------------------------}
    : : : : //{ Initialize }
    : : : :
    : : : : void init(){
    : : : : ifile = stdin; //fopen("test.q", "r");
    : : : : ofile = stdout;
    : : : : GetChar();
    : : : :
    : : : : if ((KWlist=(char **) malloc(6))==NULL) Abort("malloc error");
    : : : : [blue]/*
    : : : : Here you only allocate space for 6 characters, which is not enough to store the 5
    : : : : following strings
    : : : : */[/blue]
    : : : : KWlist[0] = "IF";
    : : : : KWlist[1] = "ELSE";
    : : : : KWlist[2] = "END";
    : : : : KWlist[3] = "ENDIF";
    : : : : KWlist[4] = "1234";
    : : : : }
    : : : :
    : : : [/code]
    : : : I thought I was declaring a an array of pointers to strings.
    : : : Doesn't "Hello" a 'return' a pointer to char.
    : : : Then I move that pointer to an array of 6 bytes.
    : : : The "Hello" is declared on the heap.
    : : : [code]
    : : : :
    : : : : //{--------------------------------------------------------------}
    : : : : //{ Main Program }
    : : : :
    : : : : int main(){
    : : : : init();
    : : : :
    : : : : char* c;
    : : : : //scanf("%s",c); //this line works
    : : : : [blue]/*
    : : : : It's amazing the line with scanf works. Normally, you should allocate space to store
    : : : : the chars before calling scanf
    : : : : */[/blue]
    : : : : c = scan(); //but this doesn't
    : : : : printf("%s
    ", c);
    : : : : printf("%d
    ", Lookup(KWlist, c, 4)); //if I put a three here it works but not if it's a four and scan() is used.
    : : : :
    : : : : free(c);
    : : : : free(KWlist);
    : : : :
    : : : : return 0;
    : : : : }
    : : : : [/code]
    : : :
    : : Yes, sorry, you're right. But remember that if you assign these string constants to the pointers in KWlist, you should not modify these strings later.
    : : I am working on your code now and I'll try to post something later if I have time.
    : :
    : : Steph
    : :
    : Why can't I modify them?
    : [code]
    : int i = 0;
    : i = 2;
    : [/code]
    : Here i is also declared on the heap, and I can modify it too.
    :
    I'll give an example to make things clearer. There's a difference between these two pieces of code:
    [code]
    /*EXAMPLE 1*/
    char *p="Hello";

    /*EXAMPLE 2*/
    char p[]="Hello";

    /*EXAMPLE 3*/
    char p[6]="Hello";
    [/code]

    EX2 and EX3 are the same except the fact that in EX2 the compiler computes the size itself.
    In EX1, what is allocated on the stack is one pointer to char; the string "Hello" is not stored on the stack but in a special segment of memory where constants are stored. This address in the constant memory segment is assigned to the variable p. But the memory block pointed to by p should not be modified because it belongs to the constant segment.

    In EX2 or EX3, 6 bytes are allocated on the stack, one for each character in the string, and these bytes are assigned the corresponding chars in the string. Then p represents the address of this 6-byte-wide block of memory. Of course, these bytes can be freely modified.

    I hope I am clear in my explanations.

    Steph
  • : I'll give an example to make things clearer. There's a difference between these two pieces of code:
    : [code]
    : /*EXAMPLE 1*/
    : char *p="Hello";
    :
    : /*EXAMPLE 2*/
    : char p[]="Hello";
    :
    : /*EXAMPLE 3*/
    : char p[6]="Hello";
    : [/code]
    :
    : EX2 and EX3 are the same except the fact that in EX2 the compiler computes the size itself.
    : In EX1, what is allocated on the stack is one pointer to char; the string "Hello" is not stored on the stack but in a special segment of memory where constants are stored. This address in the constant memory segment is assigned to the variable p. But the memory block pointed to by p should not be modified because it belongs to the constant segment.
    :
    : In EX2 or EX3, 6 bytes are allocated on the stack, one for each character in the string, and these bytes are assigned the corresponding chars in the string. Then p represents the address of this 6-byte-wide block of memory. Of course, these bytes can be freely modified.
    :
    : I hope I am clear in my explanations.
    :
    : Steph
    :
    Thanks for clearing that up.
    I don't want to change those bytes, I only whant to compare them in the Lookup func.

    Is stack and heap the same thing? I'm confusing them...

    ...OK, now I've read a little, and here's a good description:

    Constants are declared in the constant segment, wich is located 'in the code'.
    Variables are declared on the stack, wich is located on the high end of the memmory in a stack way.
    Malloc declares data on the heap, wich is located on the low end of the memmory in a data way.
  • : : I'll give an example to make things clearer. There's a difference between these two pieces of code:
    : : [code]
    : : /*EXAMPLE 1*/
    : : char *p="Hello";
    : :
    : : /*EXAMPLE 2*/
    : : char p[]="Hello";
    : :
    : : /*EXAMPLE 3*/
    : : char p[6]="Hello";
    : : [/code]
    : :
    : : EX2 and EX3 are the same except the fact that in EX2 the compiler computes the size itself.
    : : In EX1, what is allocated on the stack is one pointer to char; the string "Hello" is not stored on the stack but in a special segment of memory where constants are stored. This address in the constant memory segment is assigned to the variable p. But the memory block pointed to by p should not be modified because it belongs to the constant segment.
    : :
    : : In EX2 or EX3, 6 bytes are allocated on the stack, one for each character in the string, and these bytes are assigned the corresponding chars in the string. Then p represents the address of this 6-byte-wide block of memory. Of course, these bytes can be freely modified.
    : :
    : : I hope I am clear in my explanations.
    : :
    : : Steph
    : :
    : Thanks for clearing that up.
    : I don't want to change those bytes, I only whant to compare them in the Lookup func.
    :
    : Is stack and heap the same thing? I'm confusing them...
    :
    : ...OK, now I've read a little, and here's a good description:
    :
    : Constants are declared in the constant segment, wich is located 'in the code'.
    : Variables are declared on the stack, wich is located on the high end of the memmory in a stack way.
    : Malloc declares data on the heap, wich is located on the low end of the memmory in a data way.
    :

    The stack is used for all the variables declared in the different functions and for parameters. The heap is used to allocate memory dynamically with malloc(), calloc()...
    I've something that compiles, but it has to be tested now.

    [code]
    #include
    #include
    #include


    char look,*KWlist[5];
    FILE *ifile,*ofile;


    void GetChar(void)
    {
    look=fgetc(ifile);
    }


    void Expected(char *s)
    {
    printf("Error: %s Expected
    ",s);
    abort();
    }


    void match(char x)
    {
    char c[3]="
    ";

    if (look==x) GetChar();
    else
    {
    c[0]=x;
    Expected(c);
    }
    }


    char upcase(char c)
    {
    if (c>='a' && c<='z') c+='A'-'a';
    return c;
    }


    int IsAlpha(char c)
    {
    c=upcase(c);
    return c>='A' && c<='Z';
    }


    int IsDigit(char c)
    {
    return c>='0' && c<='9';
    }


    int IsOp(char c)
    {
    return c=='+' || c=='-' || c=='*' || c=='/' || c=='<' || c=='>' || c==':' ||
    c=='=' || c=='!';
    }


    int IsAlNum(char c)
    {
    return IsAlpha(c) || IsDigit(c);
    }


    int IsWhite(char c)
    {
    return c==' ' || c==' ' || c=='
    ';
    }


    void skipWhite(void)
    {
    while (IsWhite(look)) GetChar();
    }


    void Fin(void)
    {
    if (look=='
    ') GetChar();
    if (look=='
    ') GetChar();
    }


    int Lookup(char **list,char *s,int n)
    {
    while (n--)
    if (!strcmp(list[n],s)) return 1;
    return 0;
    }


    char *getName(char *buf)
    {
    char *p;

    p=buf;
    if (!IsAlpha(look)) Expected("Name");
    while (IsAlNum(look))
    {
    *p=upcase(look);
    ++p;
    GetChar();
    }
    *p=0;
    skipWhite();
    return buf;
    }


    char *getNum(char *buf)
    {
    char *p;

    p=buf;
    if (!IsDigit(look)) Expected("Integer");
    while (IsDigit(look))
    {
    *p++=look;
    GetChar();
    }
    *p=0;
    skipWhite();
    return buf;
    }


    char *getOp(char *buf)
    {
    char *p;

    p=buf;
    if (!IsOp(look)) Expected("Operator");
    while (IsOp(look))
    {
    *p++=look;
    GetChar();
    }
    *p=0;
    skipWhite();
    return buf;
    }


    char *scan(char *buf)
    {
    skipWhite();
    /*while (look=='
    ') Fin();*/
    if (IsAlpha(look)) return getName(buf);
    else if (IsDigit(look)) return getNum(buf);
    else if (IsOp(look)) return getOp(buf);
    else
    {
    *buf=look;
    buf[1]=0;
    GetChar();
    return buf;
    }
    }


    void init(void)
    {
    ifile=fopen("test.txt","r");
    ofile=stdout;
    GetChar();
    KWlist[0]="IF";
    KWlist[1]="ELSE";
    KWlist[2]="END";
    KWlist[3]="ENDIF";
    KWlist[4]="1234";
    }


    int main(void)
    {
    char c[512];

    init();
    scan(c);
    fclose(ifile);
    printf("%s
    ",c);
    printf("%d
    ",Lookup(KWlist,c,5));
    return 0;
    }
    [/code]

    Steph
  • : : You are not using pointers correctly. You declared char*, so you must allocate memory to it before use. Or not declare it as a pointer at all.
    : : [code]
    : : char* c = new char; //c++
    : : char* c = (char*)malloc(sizeof(char) * 1); //c
    : : char c; //another option
    : : [/code]
    : :
    : : Hope that helps,
    : : Mortissus
    : :
    :
    : This is C, it doesn't have new
    :
    Opps, I didn't read your post correctly. Disregard the previus post. Sorry.

    But I am using the pointers correctly. If I'm not, wich func is wrong?
  • : : : You are not using pointers correctly. You declared char*, so you must allocate memory to it before use. Or not declare it as a pointer at all.
    : : : [code]
    : : : char* c = new char; //c++
    : : : char* c = (char*)malloc(sizeof(char) * 1); //c
    : : : char c; //another option
    : : : [/code]
    : : :
    : : : Hope that helps,
    : : : Mortissus
    : : :
    : :
    : : This is C, it doesn't have new
    : :
    : Opps, I didn't read your post correctly. Disregard the previus post. Sorry.
    :
    : But I am using the pointers correctly. If I'm not, wich func is wrong?
    :
    What is wrong in the way you use pointers is the fact that you do not always allocate memory before writing to the location pointed to by the pointer. For example, you need to allocate memory before calling scanf().
    By the way, I tested the corrected code and it appears to work.

    Steph

  • : What is wrong in the way you use pointers is the fact that you do not always allocate memory before writing to the location pointed to by the pointer. For example, you need to allocate memory before calling scanf().
    : By the way, I tested the corrected code and it appears to work.
    :
    : Steph
    :
    What was wrong using scan()?

    It worked with scanf(). If I should have allocated memmory for c and didn't it should give a segmentation fault, but it did not.

  • :
    : : What is wrong in the way you use pointers is the fact that you do not always allocate memory before writing to the location pointed to by the pointer. For example, you need to allocate memory before calling scanf().
    : : By the way, I tested the corrected code and it appears to work.
    : :
    : : Steph
    : :
    : What was wrong using scan()?
    :
    : It worked with scanf(). If I should have allocated memmory for c and didn't it should give a segmentation fault, but it did not.
    :
    :
    Your call to scan() was OK since scan() calls functions which allocate memory (except the fact that there were other errors in these functions; they are corrected in the version I posted). What concerns scanf(), I am sure you need to allocate memory before calling scanf(). Check out the doc of this function. Such programming errors often lead to segmentation faults but not always. If you are "lucky", it will just overwrite other variables in your program. Segmentation faults occur when your program attempts to write to a block of memory which does not belong to your program.

    Steph
  • : :
    : : : What is wrong in the way you use pointers is the fact that you do not always allocate memory before writing to the location pointed to by the pointer. For example, you need to allocate memory before calling scanf().
    : : : By the way, I tested the corrected code and it appears to work.
    : : :
    : : : Steph
    : : :
    : : What was wrong using scan()?
    : :
    : : It worked with scanf(). If I should have allocated memmory for c and didn't it should give a segmentation fault, but it did not.
    : :
    : :
    : Your call to scan() was OK since scan() calls functions which allocate memory (except the fact that there were other errors in these functions; they are corrected in the version I posted). What concerns scanf(), I am sure you need to allocate memory before calling scanf(). Check out the doc of this function. Such programming errors often lead to segmentation faults but not always. If you are "lucky", it will just overwrite other variables in your program. Segmentation faults occur when your program attempts to write to a block of memory which does not belong to your program.
    :
    : Steph
    :
    To help this I think I always should init all pointers to null.
    Your code was good, thanks.
    I didn't like the intends and the funcs shouldn't return a pointer to char so I rewrote them:
    [code]
    void getOp(char *c){
    char *p;
    p = c;
    if(!IsOp(look)) Expected("Integer");
    while(IsOp(look)){
    *p = upcase(look);
    ++p;
    GetChar();
    }
    *p = 0;
    skipWhite();
    }
    //and similar with the others, getNum and getName

    void scan(char* c){
    skipWhite();
    while(look == '
    ')
    Fin();

    if(IsAlpha(look))
    getName(c);
    else if(IsDigit(look))
    getNum(c);
    else if(IsOp(look))
    getOp(c);
    else {
    *c = look;
    ++c;
    *c = 0;
    --c;
    GetChar();
    }
    }


    [/code]

    I'm still not sure what the problem was...


    : (except the fact that there were other errors in these functions; they are corrected in the version I posted)

    What errors?
  • : : :
    : : : : What is wrong in the way you use pointers is the fact that you do not always allocate memory before writing to the location pointed to by the pointer. For example, you need to allocate memory before calling scanf().
    : : : : By the way, I tested the corrected code and it appears to work.
    : : : :
    : : : : Steph
    : : : :
    : : : What was wrong using scan()?
    : : :
    : : : It worked with scanf(). If I should have allocated memmory for c and didn't it should give a segmentation fault, but it did not.
    : : :
    : : :
    : : Your call to scan() was OK since scan() calls functions which allocate memory (except the fact that there were other errors in these functions; they are corrected in the version I posted). What concerns scanf(), I am sure you need to allocate memory before calling scanf(). Check out the doc of this function. Such programming errors often lead to segmentation faults but not always. If you are "lucky", it will just overwrite other variables in your program. Segmentation faults occur when your program attempts to write to a block of memory which does not belong to your program.
    : :
    : : Steph
    : :
    : To help this I think I always should init all pointers to null.
    : Your code was good, thanks.
    : I didn't like the intends and the funcs shouldn't return a pointer to char so I rewrote them:
    : [code]
    : void getOp(char *c){
    : char *p;
    : p = c;
    : if(!IsOp(look)) Expected("Integer");
    : while(IsOp(look)){
    : *p = upcase(look);
    : ++p;
    : GetChar();
    : }
    : *p = 0;
    : skipWhite();
    : }
    : //and similar with the others, getNum and getName
    :
    : void scan(char* c){
    : skipWhite();
    : while(look == '
    ')
    : Fin();
    :
    : if(IsAlpha(look))
    : getName(c);
    : else if(IsDigit(look))
    : getNum(c);
    : else if(IsOp(look))
    : getOp(c);
    : else {
    : *c = look;
    : ++c;
    : *c = 0;
    : --c;
    : GetChar();
    : }
    : }
    :
    :
    : [/code]
    :
    : I'm still not sure what the problem was...
    :
    :
    : : (except the fact that there were other errors in these functions; they are corrected in the version I posted)
    :
    : What errors?
    :
    In fact, there were no errors in these functions (except in match() but it is not called). Sorry, I wrote this without reading your code again :-(. However, there were a few useless statements:

    [b]In Lookup()[/b]
    There is no need to compare just the first character of list[n] and s and if they are the same then compare the whole strings. Why don't you only compare the entire strings?

    [b]In getNum()[/b]
    It is useless to call upcase() in the while loop since look is a digit here.

    [b]In getOp()[/b]
    Same thing than in getNum().

    But as you can see it is of less importance.
    What concerns the cause of the problem, I am not sure at present but I'll think about it and tell you if I find something.

    Steph
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories