-3

For the code below, I am going to read tokens, for example, x, y, and z, and allocate them into a list of tokens' lexeme. The code is shown below:

int parse_varlist(void)
  {
  token = lexer.GetToken();
  char* lexeme = (char*)malloc(sizeof(token.lexeme) + 1);
  memcpy(lexeme, (token.lexeme).c_str(), (token.lexeme).size() + 1);

  addList(lexeme);     //This function is used to add tokens' lexeme into a 
                         list

  if (token.token_type == ID)    //ID is token's type
  {     

    token = lexer.GetToken();     //read next token

        parse_varlist();          //let parse_varlist() call itself to add 
                                   tokens' lexeme into list
        printList();         // print list of token's lexeme

    }


  else {
      cout << "\n Syntax Error \n";
   }
    free(lexeme);
    return(0);

}

// this is the code of addList():
void addList(char* lexeme) {

if (symbolTable == NULL) {
    sTable* newEntry = (sTable *)malloc(sizeof(sTable));
    sTableEntry* newItem = (sTableEntry *)malloc(sizeof(sTableEntry));

    newItem->name = lexeme;
    newEntry->next = NULL;
    newEntry->prev = NULL;
    symbolTable = newEntry;
}

Suppose we are going to read x, y and store their lexeme into the list. Currently, I can get these two tokens. But, after calling printList() I can only have x in my list.

I checked the possible solution online. I may use calloc() instead malloc() to allocated these memory? But, for the list that I am trying to create, am I allocating the memory into a single block or multiple block? Since this is one significant between calloc() and malloc():

enter image description here

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 4
    Are you programming C or C++? They are two very different languages, so please use only one language-tag. – Some programmer dude Aug 05 '17 at 06:14
  • @Someprogrammerdude He's using C++, but it looks like almost entirely C. – user2296177 Aug 05 '17 at 06:16
  • 2
    Regarding the last point in the linked image, you might want to read [Do I cast the result of malloc?](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) (Which is specific to C, C++ is ***different*** which is why it's so important to use the correct tags). – Some programmer dude Aug 05 '17 at 06:17
  • What is the implementation of addList? – fileyfood500 Aug 05 '17 at 06:17
  • If x and y are each lexed to strings, it sounds like you are writing them both to the same index of a list? – fileyfood500 Aug 05 '17 at 06:19
  • And what is `alloc`? Do you mean `calloc`? And the "block" thing in the linked image is a red herring. Doing `malloc(20 * sizeof(int))` and `calloc(20, sizeof(int))` will both allocate a *single contiguous block* of memory of the same size. – Some programmer dude Aug 05 '17 at 06:19
  • 3
    If you're writing in C++, you should not be using `malloc()`. If you're writing in C, you should not be using `cout << "\nSyntax Error\n";` (and you shouldn't put spaces at the start and end of the line of output). So it is crucial you decide which language you are working in, And, AFAIK, `alloc()` isn't a standard function — you need to identify which library you are working with (URL to the documentation would be good). – Jonathan Leffler Aug 05 '17 at 06:19
  • 1
    I dunno where you found that table, but the misinformation in the first line of the table is staggering. It is wrong. Grotesquely wrong. There's a nugget of truth behind it, but it is much more misleading than helpful. `calloc()` allocates a single block of memory, but the size of that block is described in terms of 'number of items' and 'size of each item'. (The use of English leaves much to be desired, and the use of `int ptr;Ptr = calloc(…);` is bad too; both C and C++ are case-sensitive languages.) I recommend ignoring the source of that table as a supply of useful information. – Jonathan Leffler Aug 05 '17 at 06:32
  • The discussion of typecasting the result of `malloc()` and `calloc()` is inconsistent with the example code, too. Also, the rules are different in C and C++ — the cast is mandatory in C++, and permissible but not strictly necessary in C (see [Should I cast the result of `malloc()`?](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) — but I'll observe I don't wholly agree with the conclusions reached). (And using a discussion of C when working in C++ is going to lead you into trouble. Use C++ references to learn about C++!) – Jonathan Leffler Aug 05 '17 at 06:38

2 Answers2

3

The following lines

char* lexeme = (char*)malloc(sizeof(token.lexeme) + 1);
memcpy(lexeme, (token.lexeme).c_str(), (token.lexeme).size() + 1);

indicate to me that token.lexeme is most likely a std::string. In that case, the value of sizeof(token.lexeme) + 1 is wrong. You need to use token.lexeme.size() + 1 instead.

But then, if you are using std::string, why bother with malloc and free? You can just use std::string for lexeme also.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

If you want to store objects in contiguous memory I'd suggest simply using a std::vector. You get all the convenience of the container, contiguous memory and no need to manage memory yourself.

If you insist on manual memory management, then at least use new/delete rather than malloc/free in C++. The former calls object constructors/destructors, the latter does not.

Also; I'd discourage the use of C "strings" - use std::string instead and prefer nullptr over NULL.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70