我的程序没有正确释放 space
My program is not deallocating space correctly
我这里有这段代码可以标记字符串。此行检查字符串是否有引号,returns 是否为不带引号的字符串。如果我从用户那里得到一些东西,例如 Hello "nice" day
,它将 return hello nice day
:
char* str = take_quotes(line, stderr);
函数 take_quotes
正在分配 space 所以我需要在我的标记化函数中取消分配 space。
我认为在我使用这条线之后我可以在 return 之前释放 space 我的令牌,但是当我这样做时我丢失了我的令牌中的任何东西。我应该如何释放 return 从 take_quotes
编辑的 space?
char** tokenize(char* line){
if(line == NULL)
return NULL;
char* str = take_quotes(line, stderr); //free space
char **tokens = malloc( sizeof( char * ) );
*tokens = NULL;
size_t n = 1;
const char *delim = " \t \n";
char *p = strtok( str, delim );
int success = p != NULL;
while ( success )
{
char **tmp = realloc( tokens, ( n + 1 ) * sizeof( char * ) );
if ( tmp == NULL )
{
free( tokens );
tokens = NULL;
success = 0;
}
else
{
tokens = tmp;
tokens[n - 1] = p;
tokens[n] = NULL;
++n;
p = strtok( NULL, delim );
success = p != NULL;
}
}
free(str);
str = NULL;
return tokens;
}
当我换行时
tokens[n - 1] = p;
到
tokens[n - 1] = strdup(p);
我在 Valgrind 中遇到很多错误
==8175== LEAK SUMMARY:
==8175== definitely lost: 12 bytes in 3 blocks
==8175== indirectly lost: 0 bytes in 0 blocks
==8175== possibly lost: 6 bytes in 1 blocks
==8175== still reachable: 0 bytes in 0 blocks
==8175== suppressed: 0 bytes in 0 blocks
==8175==
==8175== For lists of detected and suppressed errors, rerun with: -s
==8175== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
strtok
通过在字符串的分隔符处插入 NUL 终止字节来标记给定字符串 就地 。没有分配额外的内存。当您释放 str
时,您正在破坏包含这些标记的内存。
一种方法是复制您的令牌,一路为每个令牌分配内存。
strdup
可用于此目的:
tokens[n - 1] = strdup(p);
如果 strdup
在您的系统上不可用,那么您将不得不重写其功能(提示:strlen
+ malloc
+ strcpy
,并且不要不要忘记 NUL 终止字节的附加 space!)。
当需要释放 tokens
时,您必须首先释放它包含的每个单独元素。
释放锯齿状数组的每个元素的人为示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void free_tokens(char **tokens) {
for (char **t = tokens; *t != NULL; t++)
free(*t);
free(tokens);
}
int main(void) {
char **tokens = malloc(3 * sizeof *tokens);
tokens[0] = strdup("hello");
tokens[1] = strdup("world");
tokens[2] = NULL;
for (char **t = tokens; *t != NULL; t++)
printf("token:[%s]\n", *t);
free_tokens(tokens);
}
我这里有这段代码可以标记字符串。此行检查字符串是否有引号,returns 是否为不带引号的字符串。如果我从用户那里得到一些东西,例如 Hello "nice" day
,它将 return hello nice day
:
char* str = take_quotes(line, stderr);
函数 take_quotes
正在分配 space 所以我需要在我的标记化函数中取消分配 space。
我认为在我使用这条线之后我可以在 return 之前释放 space 我的令牌,但是当我这样做时我丢失了我的令牌中的任何东西。我应该如何释放 return 从 take_quotes
编辑的 space?
char** tokenize(char* line){
if(line == NULL)
return NULL;
char* str = take_quotes(line, stderr); //free space
char **tokens = malloc( sizeof( char * ) );
*tokens = NULL;
size_t n = 1;
const char *delim = " \t \n";
char *p = strtok( str, delim );
int success = p != NULL;
while ( success )
{
char **tmp = realloc( tokens, ( n + 1 ) * sizeof( char * ) );
if ( tmp == NULL )
{
free( tokens );
tokens = NULL;
success = 0;
}
else
{
tokens = tmp;
tokens[n - 1] = p;
tokens[n] = NULL;
++n;
p = strtok( NULL, delim );
success = p != NULL;
}
}
free(str);
str = NULL;
return tokens;
}
当我换行时
tokens[n - 1] = p;
到
tokens[n - 1] = strdup(p);
我在 Valgrind 中遇到很多错误
==8175== LEAK SUMMARY:
==8175== definitely lost: 12 bytes in 3 blocks
==8175== indirectly lost: 0 bytes in 0 blocks
==8175== possibly lost: 6 bytes in 1 blocks
==8175== still reachable: 0 bytes in 0 blocks
==8175== suppressed: 0 bytes in 0 blocks
==8175==
==8175== For lists of detected and suppressed errors, rerun with: -s
==8175== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
strtok
通过在字符串的分隔符处插入 NUL 终止字节来标记给定字符串 就地 。没有分配额外的内存。当您释放 str
时,您正在破坏包含这些标记的内存。
一种方法是复制您的令牌,一路为每个令牌分配内存。
strdup
可用于此目的:
tokens[n - 1] = strdup(p);
如果 strdup
在您的系统上不可用,那么您将不得不重写其功能(提示:strlen
+ malloc
+ strcpy
,并且不要不要忘记 NUL 终止字节的附加 space!)。
当需要释放 tokens
时,您必须首先释放它包含的每个单独元素。
释放锯齿状数组的每个元素的人为示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void free_tokens(char **tokens) {
for (char **t = tokens; *t != NULL; t++)
free(*t);
free(tokens);
}
int main(void) {
char **tokens = malloc(3 * sizeof *tokens);
tokens[0] = strdup("hello");
tokens[1] = strdup("world");
tokens[2] = NULL;
for (char **t = tokens; *t != NULL; t++)
printf("token:[%s]\n", *t);
free_tokens(tokens);
}