其他strust中具有结构的动态数组的Valgrind错误

时间:2018-12-05 07:04:55

标签: c valgrind

我的结构像:

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)Valgrind告诉我这个错误:

==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 :(得分:1)

您在此处访问范围。

   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';

请考虑您在\nsymb=9条件为假时输入了if (avl_sy <= symb),并且您不会重新分配。

现在symb++;将成为symb=10,并以input == '\n'的身份退出循环。

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