Проблемы утечки памяти при разбиении строки в C - PullRequest
0 голосов
/ 15 ноября 2010

Я пытаюсь разбить строку в соответствии со следующими правилами:

  1. слова без "" вокруг них должны рассматриваться как отдельные строки
  2. все, что "" вокруг нее должно бытьрассматривается как одна строка

Однако, когда я запускаю ее в valgrind, я получаю недопустимые освобождения и ошибки размера чтения, но если я удаляю два освобождения, я получаю утечку памяти.Если бы кто-нибудь мог указать мне правильное направление, я был бы признателен за это

Код, который вызывает split_string

    char *param[5];
    for(i = 0;i < 5;i++) {
            param[i] = NULL;
    }
    char* user = getenv("LOGNAME");
    char tid[9];
    char* instring = (char*) malloc(201);

    /
    while((printf("%s %s >",user,gettime(tid)))&&(instring
            =fgets(instring,201,stdin)) != NULL) {
            int paramsize = split_string(param, instring);

Код, который пытается освободить параметр

                for(i = 0;i < 5;i++) {
                if(param[i] != NULL) {
                    free(param[i]);
                    fprintf(stderr,"%d",i);
                }
            }

    int split_string(char** param, char* string) {
    int paramplace = 0; //hvor vi er i param
    int tempplace = 0; //hvor i temp vi er

    char* temp = malloc(201); 
    int command = 0; 
    int message = 0; 
    for(; (*string != '\0') && (*string != 10) && paramplace < 4; string++) {
            if((*string == ' ') && (message == 0)) {
                    if(command == 1) {
                        temp[tempplace] = '\0'; 
                        param[paramplace++] = temp; 
                        tempplace = 0;
                        command = 0;
                    }
            }
            else {
                    if(*string =='"') {
                            if(message == 0) message = 1;
                            else message = 0;
                    }
                    if(command == 0) {
                            free(temp);
                            temp = malloc(201);
                    }
                    command = 1;
                    if(*string != '"') {
                            temp[tempplace++] = *string;
                    }
            }
    }
    if(command == 1) {
            temp[tempplace] = '\0';
            param[paramplace++] = temp;
    }
    param[paramplace] = NULL;
    free(temp);
    return paramplace;
}

Ответы [ 5 ]

2 голосов
/ 15 ноября 2010

Насколько я вижу, вы хотите поместить строки разделения в param в виде массива указателей (предположительно, ответственный за их освобождение). В первой ветви оператора if в вашем цикле вы делаете это, назначая текущий буфер temp этому месту. Однако, как только вы начинаете новую строку (когда comnmand == 0, вы освобождаете это пространство, делая предыдущий указатель записи param недействительным.

Освободить каждый указатель только один раз. Я не исключаю других утечек в этом коде: я думаю, что вы можете упростить свой конечный автомат (и, возможно, найти другие ошибки в результате).

1 голос
/ 15 ноября 2010

Когда вы освобождаете временный буфер, вы также освобождаете буфер param [], в котором хранятся ваши токены. С другой стороны, если вы не вызовете free(temp), чего не следует делать, то вызывающая сторона вашей функции будет отвечать за вызов free(param[n]), когда токены не нужны.

0 голосов
/ 15 ноября 2010

Благодаря всем комментариям я нашел ответ. Проблема заключалась в том, что первый malloc перед циклом for является излишним, поскольку будет еще один, прежде чем он начнет вводить temp в param, и, следовательно, не было указателей на первый malloc, поэтому он был просто потерян.

0 голосов
/ 15 ноября 2010

Трудно понять ваш код.Я предлагаю вместо этого использовать sscanf.

Вы можете использовать строку формата, подобную этой:

"\"%[^\"]\"%n"

Узнайте, что она делает.

Я написал пример:

if( sscanf( string, "\"%[^\"]\"%n", matchedstring, &bytesread ) )
{
    handlestring( matchedstring );
    string += bytesread;
}
else if( sscanf( string, "%s%n", matchedstring, &bytesread ) )
{
    handlestring( matchedstring );
    string += bytesread;
}
else
{
    handleexception();
}

Не проверено.:)

0 голосов
/ 15 ноября 2010

Может быть, вы не удаляете права free ()? Фактическая проблема может быть в коде, который вызывает split_string. Вы можете показать это?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...