代码缩进程序给出Valgrind错误,无法弄清楚为什么

时间:2016-06-24 18:34:45

标签: c debugging memory-leaks malloc valgrind

我正在进行MOOC任务,并遇到了严重的障碍。此函数的目的是获取表示某些代码的字符串和“pad”字符串,并返回一个字符串,该字符串是输入代码的正确缩进版本,使用“pad”作为缩进。

我一直得到Valgrind错误,显然是不同的输出(他们为错误示例显示的输出与我的耸肩相同)。我已经查看了类似Valgrind错误的所有帖子,但是空洞地找出了究竟出了什么问题。下面包括函数和Valgrind错误。

C代码:

/* Indent the C-code at memory block <indent>. String <pad> represents
 * one block of indentation. Only opening curly braces '{' increase the
 * indentation level, and closing curly braces '}' decrease the indentation level.
 * Return the pointer to the code after modification.
 * Calling code is responsible of freeing only the memory block returned by
 * the function.
 */
char *indent(char *input, const char *pad)
{
    // First, find number of pads to add (for malloc precision)
    unsigned int num_pads = 0;
    unsigned int level = 0;
    char *scan = input;

    while (*scan) {
        if (*scan == '{') {
            level++;
        }
        if (*scan == '}') {
            level -= (level) ? 1 : 0;
            num_pads--;
        }
        if (*scan == '\n') {
            num_pads += level;
        }
        scan++;
    }

    // Then, add the pads
    unsigned int pad_size = strlen(pad);
    unsigned int new_buffsize = strlen(input) + 1 + (num_pads * pad_size);

    char *out_buff = malloc(new_buffsize + 1);  // Address is 0 bytes after a block size of -- alloc'd
    level = 0;

    char* read_head = input;
    char* write_head = out_buff;

    while (*read_head) {
        *write_head = *read_head;   // Invalid write of size 1
        if (*read_head == '{') {
            level++;
        }
        if (*read_head == '}') {
            write_head -= (level) ? pad_size : 0;
            level -= (level) ? 1 : 0;
            *write_head = *read_head;
        }

        write_head++;
        if (*read_head == '\n') {

            for (unsigned int i = 0; i < level; i++) {
                strncpy(write_head, pad, pad_size);   // Invalid write of size 1 [fixed maybe]
                write_head += pad_size;
            }
        }
        read_head++;

    }

    *write_head = '\0';

    free(input);
    return out_buff;
}

Valgrind的:

==13133== Memcheck, a memory error detector
==13133== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==13133== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==13133== Command: ./main
==13133==
-- Original:
// This is a test file
int main(void) {
    /* comment
     block */
    printf("juu\n");
    while (1)
    {
        // Another comment
        while (2) {
            printf("jaa\n");
        }
    }
}
-- Comments removed:
int main(void) {

    printf("juu\n");
    while (1)
    {
        while (2) {
            printf("jaa\n");
        }
    }
}
==13133== Invalid write of size 1
==13133==    at 0x100000D4C: indent (polisher.c:205)
==13133==    by 0x100000904: main (main.c:20)
==13133==  Address 0x100a7d764 is 0 bytes after a block of size 132 alloc'd
==13133==    at 0x100008EBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==13133==    by 0x100000D11: indent (polisher.c:197)
==13133==    by 0x100000904: main (main.c:20)
==13133==
-- After indenting:
int main(void) {

    printf("juu\n");
    while (1)
    {
        while (2) {
            printf("jaa\n");
        }
    }
}
==13133==
==13133== HEAP SUMMARY:
==13133==     in use at exit: 26,466 bytes in 190 blocks
==13133==   total heap usage: 273 allocs, 83 frees, 37,049 bytes allocated
==13133==
==13133== 2,064 bytes in 1 blocks are possibly lost in loss record 56 of 62
==13133==    at 0x10000917C: malloc_zone_malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==13133==    by 0x1004F9EFD: _objc_copyClassNamesForImage (in /usr/lib/libobjc.A.dylib)
==13133==    by 0x1004ED182: protocols() (in /usr/lib/libobjc.A.dylib)
==13133==    by 0x1004ED093: readClass(objc_class*, bool, bool) (in /usr/lib/libobjc.A.dylib)
==13133==    by 0x1004EAC13: gc_init (in /usr/lib/libobjc.A.dylib)
==13133==    by 0x1004F224E: objc_initializeClassPair_internal(objc_class*, char const*, objc_class*, objc_class*) (in /usr/lib/libobjc.A.dylib)
==13133==    by 0x1004FF132: layout_string_create (in /usr/lib/libobjc.A.dylib)
==13133==    by 0x1004ED83C: realizeClass(objc_class*) (in /usr/lib/libobjc.A.dylib)
==13133==    by 0x1004ED300: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==13133==    by 0x1004ED2E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==13133==    by 0x1004ED2E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==13133==    by 0x1004ED2E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==13133==
==13133== LEAK SUMMARY:
==13133==    definitely lost: 0 bytes in 0 blocks
==13133==    indirectly lost: 0 bytes in 0 blocks
==13133==      possibly lost: 2,064 bytes in 1 blocks
==13133==    still reachable: 0 bytes in 0 blocks
==13133==         suppressed: 24,402 bytes in 189 blocks
==13133==
==13133== For counts of detected and suppressed errors, rerun with: -v
==13133== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 16 from 16)

先谢谢你一起来看看!我现在已经打了一会儿。

0 个答案:

没有答案