免费字符错误** table
Error on free char** table
我有一个函数,它接受一个字符串并将其拆分为标记,因为我想 return 这些标记我使用 malloc 分配了一个变量。
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;
}
然后我尝试用另一个函数释放这个 table:
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);
当我尝试释放 table 时出现此错误:
*** Error in `./a.out': free(): invalid pointer: 0x00007ffd003f62b0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fdb2e5497e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x7fe0a)[0x7fdb2e551e0a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fdb2e55598c]
./a.out[0x4012d6]
错误继续...
我做错了什么?
开始于:
char** final = (char**)malloc(strlen(buffer)+1);
这会分配 strlen(buffer) + 1
字节 ,而不是 "elements" 的数量。由于 sizeof(char*)
很可能比单个字节大得多,因此您可能会在这里分配很少的内存。
由于您不知道可能有多少代币,因此您不应分配固定数量,而是使用 realloc
根据需要重新分配。
那么第二个问题:
final[i] = malloc(strlen(token[i])+1);
...
final[i] = token[i];
在第一条语句中,您为 token[i]
指向的字符串分配了足够的内存,并将指向该内存的指针分配给 final[i]
。 但是然后你立即重新分配final[i]
指向其他地方,一些你没有的记忆'来自 malloc
。您应该 copy the string 而不是重新分配指针:
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;
}
请注意,strdup
不是标准的 C 函数,但它非常普遍,足以假设它会存在。在不太可能不存在的情况下,很容易自己实现。
我有一个函数,它接受一个字符串并将其拆分为标记,因为我想 return 这些标记我使用 malloc 分配了一个变量。
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;
}
然后我尝试用另一个函数释放这个 table:
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);
当我尝试释放 table 时出现此错误:
*** Error in `./a.out': free(): invalid pointer: 0x00007ffd003f62b0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fdb2e5497e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x7fe0a)[0x7fdb2e551e0a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fdb2e55598c]
./a.out[0x4012d6]
错误继续...
我做错了什么?
开始于:
char** final = (char**)malloc(strlen(buffer)+1);
这会分配 strlen(buffer) + 1
字节 ,而不是 "elements" 的数量。由于 sizeof(char*)
很可能比单个字节大得多,因此您可能会在这里分配很少的内存。
由于您不知道可能有多少代币,因此您不应分配固定数量,而是使用 realloc
根据需要重新分配。
那么第二个问题:
final[i] = malloc(strlen(token[i])+1);
...
final[i] = token[i];
在第一条语句中,您为 token[i]
指向的字符串分配了足够的内存,并将指向该内存的指针分配给 final[i]
。 但是然后你立即重新分配final[i]
指向其他地方,一些你没有的记忆'来自 malloc
。您应该 copy the string 而不是重新分配指针:
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;
}
请注意,strdup
不是标准的 C 函数,但它非常普遍,足以假设它会存在。在不太可能不存在的情况下,很容易自己实现。