Проблемы с обработкой указателей в динамической матрице - PullRequest
1 голос
/ 06 декабря 2010

Я борюсь с указателями :(. Я пытаюсь создать функцию, которая делает что-то похожее на то, что возвращает argv. Я имею в виду, я хочу, чтобы он разделил порядок на несколько строк, каждая из которых указана по-своему чтобы ссылаться на них в квадратных скобках. (то есть: порядок [0], порядок [1]).

Я хочу сделать это для любого количества слов, поэтому я использую динамическую память. Чтобы разделить порядок я использую strtok и он работает правильно. Проблема в том, чтобы справиться с указателями:

В результате ** Я резервирую память с помощью realloc для указателей, которые указывают каждое слово, поэтому при наличии токенов я делаю следующее:

  • увеличиваю размер результата
  • Я резервирую память для указателя на токен
  • Я назначаю токен

(текст для остановки уценки)

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
    char linea[] = "send UDP 4500 50";
    char **resul=NULL;
    int numTokens,conta2;
    char *sep=" ";//character which divides the orders
    int conta=0;  //counter of the number of tokens found
    char *saveptr,*token;

    for(token=strtok_r(linea,sep,&saveptr); token!=NULL; token=strtok_r(NULL,sep,&saveptr)){
        printf("token: %s\n",token);
        printf("size: %i\n",(conta+1)*sizeof(char*));
        resul = (char **)realloc(resul,(conta+1)*sizeof(char*)); //Increase the size for the array of pointers

        resul[conta]= malloc(sizeof(char*)); //Reserve size for the pointer
        resul[conta]=token; //Asign word to the pointer
        conta++;
    }
    //Print the results
    for(conta2=0;conta2<conta;conta2++)
        printf("resul: \"%s\"\n",resul[conta2]);
    //free memory
    for(conta2=0;conta2<conta;conta2++){
        printf("liberando: %i\n",conta2);
        free(resul[conta2]);
    }
    free(resul);
    return(0);
}

Вывод:

$ ./lectura_consola 
token: send
size: 4
token: UDP
size: 8
token: 4500
size: 12
token: 50
size: 16
resul: "send"
resul: "UDP"
resul: "4500"
resul: "50"
liberando: 0
*** glibc detected *** ./lectura_consola: free(): invalid pointer: 0xbffb7f1b ***

Если я запускаю его с valgrind, чтобы увидеть ошибки в памяти, на этапе free (resul [0]) происходит следующее:

liberando: 0
==8372== Invalid free() / delete / delete[]
==8372==    at 0x40257ED: free (vg_replace_malloc.c:366)
==8372==    by 0x80489FA: main (lectura_consola.c:92)
==8372==  Address 0xbee8e28b is on thread 1's stack

С этим кодом программа сохраняет и печатает слова правильно, но в момент освобождения памяти, которую она использует, и когда она пытается освободить результат, resul [0] говорит: Неверный указатель.

Не могли бы вы сказать мне, где ошибка? Я полностью потерян, и любая помощь будет полезна

Ответы [ 2 ]

2 голосов
/ 06 декабря 2010

Проблема в том, что вы пытаетесь освободить память, которую вы не выделяли. У вас есть этот код в вашем первом цикле:

resul[conta]= malloc(sizeof(char*)); //Reserve size for the pointer
resul[conta]=token; //Asign word to the pointer

Второй оператор перезаписывает результат первого оператора, поэтому при вызове free(resul[conta]) вы пытаетесь освободить token (который является указателем на строку), а не выделенный вами указатель.

Тебе не нужно это первое утверждение в любом случае. Ваш realloc вызов резервирует место для массива указателей. Этот вызов malloc просто выделяет sizeof(char*) байтов безрезультатно (т. Е. Тратит память). А поскольку значение просто перезаписывается, в результате вы теряете эту память.

Просто удалите вызов на malloc и ваш код должен работать.

0 голосов
/ 06 декабря 2010

Насколько я помню, strtok не распределяет память, просто вставляет \ 0 между токенами, и это означает, что вы освобождаете кодовую память только для чтения - отправьте UDP 4500 50 "- это

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