我的程序没有正确释放 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);
}