【问题标题】:Continuous memory allocation in C++C++ 中的连续内存分配
【发布时间】:2017-08-05 06:12:17
【问题描述】:

对于下面的代码,我将读取令牌,例如, x、y 和 z,并将它们分配到令牌的词位列表中。代码如下:

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;
}

假设我们要读取 x, y 并将它们的词位存储到列表中。目前,我可以获得这两个令牌。但是,在调用 printList() 之后,我的列表中只能有 x

我在网上查看了可能的解决方案。我可以使用 calloc() 而不是 ma​​lloc() 来分配这些内存吗? 但是,对于我要创建的列表,我是将内存分配到单个块还是多个块中?因为这是 calloc()ma​​lloc() 之间的一个重要因素:

【问题讨论】:

  • 您是在编程 C 还是 C++?它们是两种截然不同的语言,因此请仅使用一种语言标签。
  • @Someprogrammerdude 他使用的是 C++,但看起来几乎完全是 C。
  • 关于链接图像中的最后一点,您可能需要阅读Do I cast the result of malloc?(这是特定于 C 的,C++ 是 不同这就是为什么使用正确的标签如此重要)。
  • 如果你用 C++ 编写,你不应该使用malloc()。如果您使用 C 语言编写,则不应使用 cout &lt;&lt; "\nSyntax Error\n";(并且不应在输出行的开头和结尾处放置空格)。因此,您决定使用哪种语言至关重要,而且,AFAIK,alloc() 不是标准功能 - 您需要确定您正在使用哪个库(文档的 URL 会很好)。
  • 我不知道您在哪里找到该表,但该表第一行中的错误信息令人震惊。这是错误的。大错特错。它背后有一些真相,但它更具误导性而不是帮助。 calloc() 分配单个内存块,但该块的大小以“项目数”和“每个项目的大小”来描述。 (英语的使用有很多不足之处,int ptr;Ptr = calloc(…); 的使用也很糟糕;C 和 C++ 都是区分大小写的语言。)我建议忽略该表的来源,因为它提供了有用的信息。跨度>

标签: c++ memory-management


【解决方案1】:

以下几行

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

告诉我token.lexeme 很可能是std::string。在这种情况下,sizeof(token.lexeme) + 1 的值是错误的。您需要改用token.lexeme.size() + 1

但是,如果您使用的是std::string,为什么还要使用mallocfree?您也可以将std::string 用于lexeme

【讨论】:

    【解决方案2】:

    如果您想将对象存储在连续内存中,我建议您只需使用std::vector。您可以获得容器的所有便利,连续的内存,无需自己管理内存。

    如果你坚持手动内存管理,那么至少在C++中使用new/delete而不是malloc/free。前者调用对象的构造函数/析构函数,后者不调用。

    还有;我不鼓励使用 C“字符串” - 改用 std::string 并更喜欢 nullptr 而不是 NULL

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-30
      • 2016-12-30
      • 1970-01-01
      • 2012-07-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多