c - 我什么时候释放变量decodeSet1?

标签 c malloc valgrind free

我为decodeSet1和decodeSet2分配了内存...我可以很好地释放decodeSet2,但是当释放decodeSet1并提交我的代码来尝试时,它会出现此错误“双重释放或损坏(出):0x0000000002046020 ***.. .但是当我在 valgrind 中运行代码时它没有给我错误......

这是我的代码:

#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>    // size_t type
#include <string.h>   // C strings
#include <stdint.h>   // uint64_t type

#define NUL '\0'
const size_t SETSIZE = sizeof( uint64_t ) << 3 ;
const size_t BUFSIZE = 256;
const char encodingTable[] = {'z', 'y', 'x', 'w', 'v', 'u', 't', 's', 
                              'r', 'q', 'p', 'o', 'n', 'm', 'l', 'k', 
                              'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 
                              'b', 'a', ',', '9', '8', '7', '6', '5', 
                              '4', '3', '2', '1', '0', '.', 'Z', 'Y', 
                              'X', 'W', 'V', 'U', 'T', 'S', 'R', 'Q', 
                              'P', 'O', 'N', 'M', 'L', 'K', 'J', 'I', 
                              'H', 'G', 'F', 'E', 'D', 'C', 'B', 'A'};


// Encodes a string
//
// @param st a string to be encoded
uint64_t set_encode( char * st ) {
    unsigned long long bitMask = 1;
    uint64_t set = 0;
    for(size_t x = 0; x < strlen(st); x ++){
        int indx = strchr(encodingTable, st[x]) - encodingTable;
        if(indx >= 0){
          set |= bitMask << indx;
        }
    }
    return set;
}

// The intersection of two sets
//
// @param set1 a set of characters from files or a string
// @param set2 a set of characters from files or a string
uint64_t set_intersect( uint64_t set1, uint64_t set2 ) {
    uint64_t set = 0;
    set = set1 & set2;
    return set;
}

// The union of two sets
//
// @param set1 a set of characters from files or a string
// @param set2 a set of characters from files or a string
uint64_t set_union( uint64_t set1, uint64_t set2 ) {
    uint64_t set = 0;
    set = set1 | set2;
    return set;
}

// The complement of a set
//
// @param set1 a set of characters from files or a string
uint64_t set_complement( uint64_t set1 ) {
    uint64_t set = 0;
    set = ~set1;
    return set;
}

// Takes the difference of set1 and ~set2
//
// @param set1 a set of characters from files or a string
// @param set2 a set of characters from files or a string
uint64_t set_difference( uint64_t set1, uint64_t set2 ) {
    uint64_t set = 0;
    set = set1 & ~set2;
    return set;
}

// Takes the difference of the union of set1 and set2 and 
// the intersect of set1 and set2.
//
// @param set1 a set of characters from files or a string
// @param set2 a set of characters from files or a string
uint64_t set_symdifference( uint64_t set1, uint64_t set2 ) {
    uint64_t set = 0;
    set = set_union(set1, set2) - set_intersect(set1, set2);
    return set;
}

// Takes the cardinality of a set (number of 1's in its binary
// number.
//
// @param set a set of characters from files or a string
size_t set_cardinality( uint64_t set ) {
    size_t cnt = 0;
    for (size_t x = 0; x < SETSIZE; x++){
        set >>= 1UL;
        if (set & 1){
            cnt++;
        }
    }
    return cnt;
}

// Decodes a set
//
// @param set a set of characters from files or a string
char * set_decode( uint64_t set ) {
    size_t lengthOfSet = set_cardinality(set);
    size_t indx = 0;
    char *bits = malloc(lengthOfSet + 1);
    bits[lengthOfSet] = NUL;

    for (size_t cnt = 0; set; set >>= 1){
        if (set & 1){
          bits[lengthOfSet - indx - 1] = encodingTable[cnt];
          indx += 1;
        }
        cnt += 1;
    }
    return bits;
}

// Reads a string from a file and encodes it
//
// @param fp file to be read
uint64_t file_set_encode( FILE * fp ) {
    char buf[BUFSIZE];
    uint64_t set = 0;

    while (fgets(buf, BUFSIZ, fp) != NULL){
      uint64_t tmpBuf = set_encode(buf);
      set |= tmpBuf;
    }
    fclose(fp);
    return set;
}

int main( int argc, char *argv[] ){
    int args; 
    uint64_t set1 = 0;
    uint64_t set2 = 0;
    args = argc - 1;
    char *decodeSet1 = NULL;
    char *decodeSet2 = NULL;

    if (args < 2 || args > 2){
        fprintf(stderr, "Usage: file-bitsets string1 string2");
        exit(EXIT_FAILURE);
    } else {
        FILE *pfile1 = fopen(argv[1], "r");
        if (pfile1){
          set1 = file_set_encode(pfile1);
          printf("string1:        %s\tEncoding the file:    %s\n", argv[1], argv[1]);
        } else {
            set1 = set_encode(argv[1]);
            printf("string1:        %s\tEncoding the string:    %s\n", argv[1], argv[1]);
        }

        FILE *pfile2 = fopen(argv[2], "r");
        if (pfile2){
            set2 = file_set_encode(pfile2);
            printf("string2:        %s\tEncoding the file:    %s\n\n", argv[2], argv[2]);
        } else {
            set2 = set_encode(argv[2]);
            printf("string2:        %s\tEncoding the string:    %s\n\n", argv[2], argv[2]);
        }

        printf("set1:    %#018lx\n", set1);
        printf("set2:    %#018lx\n\n", set2); 

        printf("set_intersect:    %#018lx\n", set_intersect(set1, set2));
        printf("set_union:    %#018lx\n\n", set_union(set1, set2));

        printf("set1 set_complement:    %#018lx\n", set_complement(set1));
        printf("set2 set_complement:    %#018lx\n\n", set_complement(set2));

        printf("set_difference:        %#018lx\n", set_difference(set1, set2));
        printf("set_symdifference:    %#018lx\n\n", set_symdifference(set1, set2));

        printf("set1 set_cardinality: %zu\n", set_cardinality(set1));
        printf("set2 set_cardinality: %zu\n\n", set_cardinality(set2));

        decodeSet1 = set_decode(set1);
        decodeSet2 = set_decode(set2);
        printf("members of set1: '%s'\n", decodeSet1);
        printf("members of set2: '%s'\n", decodeSet2);
    }
 -> free(decodeSet1);
    free(decodeSet2);
}

这是我提交到尝试服务器时遇到的错误:

SaholinGOD@comp:~/Desktop/$ try grd-243 hw7-1 file-bitsets.c
Copying files...done
Initializing - please wait...
ON-TIME submission of hw7-1
Compiling your submission....
gcc -ggdb -std=c99 -Wall -Wextra -pedantic  -c file-bitsets.c
gcc -ggdb -std=c99 -Wall -Wextra -pedantic -o file-bitsets file-bitsets.o  -lm
Test 1: file-bitsets Hello There  < input.1
Test 2: file-bitsets chimchiminy chimchimeny  < input.2
Test 3: file-bitsets empty aMixedBag  < input.3
Still testing...
*** Error in `file-bitsets': double free or corruption (out): 0x0000000002046020 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x77725)[0x2ac1765d1725]
/lib/x86_64-linux-gnu/libc.so.6(+0x7ff4a)[0x2ac1765d9f4a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x2ac1765ddabc]
file-bitsets[0x400ec2]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x2ac17657a830]
file-bitsets[0x400789]
======= Memory map: ========
00400000-00402000 r-xp 00000000 00:42 24942233                           /home/grader/grd-243/try_dir/Wds/wd.ShaolinGOD/file-bitsets
00601000-00602000 r--p 00001000 00:42 24942233                           /home/grader/grd-243/try_dir/Wds/wd.ShaolinGOD/file-bitsets
00602000-00603000 rw-p 00002000 00:42 24942233                           /home/grader/grd-243/try_dir/Wds/wd.ShaolinGOD/file-bitsets
02026000-02047000 rw-p 00000000 00:00 0                                  [heap]
2ac176332000-2ac176358000 r-xp 00000000 08:01 7042504                    /lib/x86_64-linux-gnu/ld-2.23.so
2ac176358000-2ac17635b000 rw-p 00000000 00:00 0 
2ac17639f000-2ac1763a1000 rw-p 00000000 00:00 0 
2ac176557000-2ac176558000 r--p 00025000 08:01 7042504                    /lib/x86_64-linux-gnu/ld-2.23.so
2ac176558000-2ac176559000 rw-p 00026000 08:01 7042504                    /lib/x86_64-linux-gnu/ld-2.23.so
2ac176559000-2ac17655a000 rw-p 00000000 00:00 0 
2ac17655a000-2ac17671a000 r-xp 00000000 08:01 7042508                    /lib/x86_64-linux-gnu/libc-2.23.so
2ac17671a000-2ac176919000 ---p 001c0000 08:01 7042508                    /lib/x86_64-linux-gnu/libc-2.23.so
2ac176919000-2ac17691d000 r--p 001bf000 08:01 7042508                    /lib/x86_64-linux-gnu/libc-2.23.so
2ac17691d000-2ac17691f000 rw-p 001c3000 08:01 7042508                    /lib/x86_64-linux-gnu/libc-2.23.so
2ac17691f000-2ac176923000 rw-p 00000000 00:00 0 
2ac176923000-2ac176939000 r-xp 00000000 08:01 7042529                    /lib/x86_64-linux-gnu/libgcc_s.so.1
2ac176939000-2ac176b38000 ---p 00016000 08:01 7042529                    /lib/x86_64-linux-gnu/libgcc_s.so.1
2ac176b38000-2ac176b39000 rw-p 00015000 08:01 7042529                    /lib/x86_64-linux-gnu/libgcc_s.so.1
2ac178000000-2ac178021000 rw-p 00000000 00:00 0 
2ac178021000-2ac17c000000 ---p 00000000 00:00 0 
7ffe33980000-7ffe339a1000 rw-p 00000000 00:00 0                          [stack]
7ffe339ce000-7ffe339d0000 r--p 00000000 00:00 0                          [vvar]
7ffe339d0000-7ffe339d2000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Still testing...
Test 10: file-bitsets  < input.10

Creating submission archive - please wait....
Files being saved:
file-bitsets.c


Submission dated 2016/11/17 19:31:28 has been completed
Your files: file-bitsets.c 

最佳答案

有一个微妙的错误,您可以通过调用 set_decode(1) 看到它。 set_cardinality(1) 将返回 0,因为 set >>= 1UL 在检查 set & 1 之前发生> 是真的。

然后,char *bits = malloc(1); 后跟:

if (1 & 1){
  bits[0 - 0 - 1] = encodingTable[cnt];

糟糕,写入 bits[-1] 会损坏堆,从而出现您所看到的错误。让 set_cardinality 返回奇数的正确值的修复应该是显而易见的,所以我将其留给您来完成。

关于c - 我什么时候释放变量decodeSet1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40667570/

相关文章:

c - 在 C 中,数组定义中的长度如何映射到寻址?

c - 使用 OpenGL 和 SDL 逐帧动画

c - 将文件读入 char 数组,然后 malloc 大小。 (C)

c - C 中 size_t 类型的 malloc 参数的限制是什么?文档说它有 UINT_MAX 的上限,但我不能超过 INT_MAX

c - 添加到 malloc 数组的值将成为 malloc 数组中的所有值

c - 使用 libgraphviz/dot 进行树可视化

c - Release 与 Debug 中的 malloc (VC 2012)

c - Valgrind "Conditional jump or move depends on uninitialised value(s)"错误

c - 这个错误在 Valgrind 中意味着什么

c - 在 C 中使用 qsort 和简单的 strcmp 函数获取段错误?