免费char **表出错

时间:2017-04-15 00:05:50

标签: c arrays char free

我有一个函数,它接受一个字符串并将其拆分为标记,因为我想返回这些标记,我使用malloc分配一个变量。

<div>
  <span>
    <tr>
      <span class="test">
        <p>Foo</p>
      </span>
    </tr>
    <div>
      <tr>
        <li>
          <p>Bar</p>
        </li>
      </tr>
    </div>
    <p>FooBar</p>
  </span>
</div>

我尝试用另一个函数释放这个表:

char** analyze(char* buffer)
{
  int i= 0;
  char* token[512];

  char** final = (char**)malloc(strlen(buffer)+1);
  if ( final == NULL ) { perror("Failed to malloc"); exit(10); }

  token[i] = strtok(buffer, " ");
  while( token[i] != NULL )
  {
    final[i] = malloc(strlen(token[i])+1);
    if( final[i] == NULL ) { perror("Failed to malloc"); exit(11); }

    final[i] = token[i];

    i++;
    token[i] = strtok(NULL, " ");
   }

   final[i] = malloc(sizeof(char));
   if( final[i] == NULL ) { perror("Failed to malloc"); exit(12); }
   final[i] = NULL;

   return final;
}

主要使用:

void free_table(char** job)
{
  int i = 0;

  while( job[i] != NULL )
  {
    free(job[i]);
    i++;
  }
  free(job[i]); //free the last 
  free(job);
}

char** job = analyze(buffer); // buffer contains the string

当我尝试释放表格时,我收到此错误:

free_table(job);

并且错误继续......

我做错了什么?

1 个答案:

答案 0 :(得分:1)

首先:

char** final = (char**)malloc(strlen(buffer)+1);

这会分配strlen(buffer) + 1 字节 ,而不是&#34;元素&#34;的数量。由于sizeof(char*)很可能比单个字节大得多,所以你可能会在这里分配很少的内存。

由于您不知道可能有多少令牌,因此您不应分配固定金额,而是根据需要使用realloc重新分配。

然后是第二个问题:

final[i] = malloc(strlen(token[i])+1);
...
final[i] = token[i];

在第一个语句中,为token[i]指向的字符串分配足够的内存,并将指向该内存的指针分配给final[i] 但是 然后你立即重新分配 final[i]指向其他地方,一些你从{{1}获得的记忆}}。你应该copy the string而不是重新分配指针:

malloc

在一个不相关的注释中,strcpy(final[i], token[i]); 不需要成为指针数组。它可以只是一个指针:

token

可能的实施示例:

char *token = strtok(...);

请注意char **analyze(char *buffer) { size_t current_token_index = 0; char **tokens = NULL; // Get the first "token" char *current_token = strtok(buffer, " "); while (current_token != NULL) { // (Re)allocate memory for the tokens array char **temp = realloc(tokens, sizeof *temp * (current_token_index + 1)); if (temp == NULL) { // TODO: Better error handling // (like freeing the tokens already allocated) return NULL; } tokens = temp; // Allocate memory for the "token" and copy it tokens[current_token_index++] = strdup(current_token); // Get the next "token" current_token = strtok(NULL, " "); } // Final reallocation to make sure there is a terminating null pointer char **temp = realloc(tokens, sizeof *temp * (current_token_index + 1)); if (temp == NULL) { // TODO: Better error handling // (like freeing the tokens already allocated) return NULL; } tokens = temp; // Terminate the array tokens[current_token_index] = NULL; return tokens; } 不是标准的C函数,但它足以让它假设它存在。在它不存在的不太可能的情况下,它很容易实现。