Ошибки Valgrind с динамическими массивами struct в другой структуре - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть структура вроде:

typedef struct Sentense{
    long int length;
    wchar_t *str;
    wchar_t **splword;
    long int count_words;
    long long int prod;
} sentense_s;

typedef struct Text{
    long int quant;
    sentense_s *sent;
} text_s;

И функции для чтения текста и работы с ним:

#ifndef MAKE_BIG
#define MAKE_BIG 10
#endif

int read_str(wchar_t **str){
    int avl_sy = MAKE_BIG;
    int symb = 0;
    *str = (wchar_t *)malloc(avl_sy * sizeof(wchar_t));
    if (!str)
        return 1;
    wchar_t input = '.';
    while (input != L'\n'){
        wscanf(L"%lc", &input);
        if (avl_sy <= symb){
            avl_sy += MAKE_BIG;
            *str = (wchar_t*)realloc(*str, avl_sy * sizeof(wchar_t));
            if (!str)
                return 1;
        }
        (*str)[symb] = input;
        symb++;
    }
    (*str)[symb] = L'\0';
    return 0;
}

int make_arr(wchar_t *temp, text_s *text){
    temp[wcslen(temp) - 1] = L'\0';
    text->quant = 0;
    long int avl_sent = MAKE_BIG;
    text->sent = (sentense_s *)malloc(avl_sent * sizeof(sentense_s));
    if (!text->sent)
        return 1;
    wchar_t *token = NULL;
    wchar_t *buffer = NULL;
    token = wcstok(temp, L".", &buffer);
    while (token != NULL){
        if (avl_sent <= text->quant){
            avl_sent += MAKE_BIG;
            text->sent = (sentense_s *)realloc(text->sent, avl_sent * sizeof(sentense_s));
            if (!text->sent)
                return 1;
        }
        text->sent[text->quant].str = (wchar_t *)malloc( (wcslen(token) + 2) * sizeof(wchar_t));
        if (!text->sent[text->quant].str)
            return 1;
        wmemcpy(text->sent[text->quant].str, token, wcslen(token) + 1);
        text->quant++;
        token = wcstok(NULL, L".", &buffer);
    }
    token = NULL;
    buffer = NULL;
    free(temp);
    return 0;
}

И есть две проблемы: 1) В некоторых тестах происходит сбой приначало программы с:

main: malloc.c:2385: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.

Но потом я запускаю во второй раз, это работает.2) Вальгринд покажи мне эти ошибки:

==11408== Invalid write of size 4
==11408==    at 0x109462: read_str (in /home/nikita/GitHub/Course-work/Code/main)
==11408==    by 0x109296: main (in /home/nikita/GitHub/Course-work/Code/main)
==11408==  Address 0x4a86878 is 0 bytes after a block of size 680 alloc'd
==11408==    at 0x4839D7B: realloc (vg_replace_malloc.c:826)
==11408==    by 0x109410: read_str (in /home/nikita/GitHub/Course-work/Code/main)
==11408==    by 0x109296: main (in /home/nikita/GitHub/Course-work/Code/main)
==11408== 
==11408== Invalid read of size 4
==11408==    at 0x483FE24: wcslen (vg_replace_strmem.c:1868)
==11408==    by 0x1094AE: make_arr (in /home/nikita/GitHub/Course-work/Code/main)
==11408==    by 0x1092C1: main (in /home/nikita/GitHub/Course-work/Code/main)
==11408==  Address 0x4a86878 is 0 bytes after a block of size 680 alloc'd
==11408==    at 0x4839D7B: realloc (vg_replace_malloc.c:826)
==11408==    by 0x109410: read_str (in /home/nikita/GitHub/Course-work/Code/main)
==11408==    by 0x109296: main (in /home/nikita/GitHub/Course-work/Code/main)
==11408== 
==11408== Invalid free() / delete / delete[] / realloc()
==11408==    at 0x48389AB: free (vg_replace_malloc.c:530)
==11408==    by 0x1092E5: main (in /home/nikita/GitHub/Course-work/Code/main)
==11408==  Address 0x4a865d0 is 0 bytes inside a block of size 680 free'd
==11408==    at 0x48389AB: free (vg_replace_malloc.c:530)
==11408==    by 0x1096B7: make_arr (in /home/nikita/GitHub/Course-work/Code/main)
==11408==    by 0x1092C1: main (in /home/nikita/GitHub/Course-work/Code/main)
==11408==  Block was alloc'd at
==11408==    at 0x4839D7B: realloc (vg_replace_malloc.c:826)
==11408==    by 0x109410: read_str (in /home/nikita/GitHub/Course-work/Code/main)
==11408==    by 0x109296: main (in /home/nikita/GitHub/Course-work/Code/main)
==11408== 

Где мои ошибки?Почему это странно работает с динамическим массивом структур?

Это темп от основного:

wchar_t *temp;

1 Ответ

0 голосов
/ 05 декабря 2018

Здесь вы выходите с привязки.

   while (input != L'\n'){
        wscanf(L"%lc", &input);
        if (avl_sy <= symb){
            avl_sy += MAKE_BIG;
            *str = (wchar_t*)realloc(*str, avl_sy * sizeof(wchar_t));
            if (!str)
                return 1;
        }
        (*str)[symb] = input;
        symb++;
    }
    (*str)[symb] = L'\0';

Представьте, что вы ввели \n, когда symb=9 и if (avl_sy <= symb) условие ложно, и вы не будете перераспределять.

Сейчасsymb++; сделает symb=10 и выйдет из цикла как input == '\n'.

    (*str)[symb] = L'\0';//(*str)[10] out of bound access.
...