C:free():无效的指针异常终止(核心转储)错误

异国情调

我不确定为什么会收到此错误,我正在运行一个隐写程序,该程序会接收一个PPM文件,并允许用户将消息编码到PPM文件中,并且尝试在valgrind中进行调试,并且发生错误:

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

struct PPM {
    char *comments;
    char *ppmname;
    unsigned int width, height, max;
    unsigned int size;
    struct Pixel**pixels;

}ppm;

struct Pixel {
    int r, g, b;
}Pixel;

static int *decimalToBinary(const char *message, unsigned int msgSize);
struct PPM * getPPM(FILE * f);
struct PPM *encode(struct PPM *im, char *message, unsigned int mSize, unsigned int secret);
void showPPM(struct PPM * im);

int main(int argc, char *argv[]){
    FILE * fin = fopen("home-cat.ppm", "r");

    if(fin == NULL) {
        perror("Cannot open file");
        exit(1);
    }

    struct PPM *p = getPPM(fin);
    struct PPM *g = encode(p, "test", 5, 2);
    showPPM(g);

    free(p->comments);
    free(p);



    return 0;
}

struct PPM * getPPM(FILE * f) {

    ppm.comments = (char *)calloc(70,sizeof(char));
    ppm.ppmname = (char *)calloc(3,sizeof(char));
    fscanf(f, "%s", ppm.ppmname);

    fgetc(f);
    fgets(ppm.comments, 70, f);
    fscanf(f, "%d %d", &ppm.width, &ppm.height);

    fscanf(f, "%d", &ppm.max);
    ppm.size = ppm.width * ppm.height;
    ppm.pixels = (struct Pixel**)malloc(ppm.width * sizeof(struct Pixel));

    for (int i=0; i<ppm.width; i++) {
        ppm.pixels[i] = (struct Pixel*)malloc(ppm.height*sizeof(struct Pixel));
    }

    for (int i=0; i<ppm.width; i++) {
        for (int j=0; j<ppm.height; j++) {
            fscanf(f, "%d %d %d", &ppm.pixels[i][j].r, &ppm.pixels[i][j].g, &ppm.pixels[i][j].b);
        }
    } 
    return &ppm;
}

void showPPM(struct PPM * im) {
    printf("%s\n", ppm.ppmname);
    printf("%s", ppm.comments);
    printf("%d %d\n", ppm.width, ppm.height);
    printf("%d\n", ppm.max);

    for (int i=0; i<ppm.width; i++) {
        for (int j=0; j<ppm.height; j++){
            printf("%d %d %d\n", ppm.pixels[i][j].r, ppm.pixels[i][j].g, ppm.pixels[i][j].b);
        }
    }
}

struct PPM *encode(struct PPM *im, char *message, unsigned int mSize, unsigned int secret) {
    int *binaryMessage = decimalToBinary(message, mSize);
    int i, j, k;
    bool unique;
    srand(secret);
    int used[40]; memset(used, -1, sizeof(used)); // might have the last two args backwards... I always forget lol
    for(i = 0; i < 39; i+=3) {
        // determine next pixel based on the user's secret (srand)
        // and without ovewrwriting a previous hidden message
        do {
            unique = true;
            j = rand() % 3; // get new number and then check if it's unique
            for(k = 0; k < i; k++) if (used[i] == j) {unique = false; break;}
        } while(!unique);
        im->pixels[j]->r = im->pixels[j]->r & ~1 | binaryMessage[i+0]; // ~1 is 11111110
        im->pixels[j]->g = im->pixels[j]->g & ~1 | binaryMessage[i+1]; // anding keeps the first 7 and clears the last
        im->pixels[j]->b = im->pixels[j]->b & ~1 | binaryMessage[i+2]; // oring will set it if the binaryMessage is set
    }
        // should make a function...
        do {
            unique = true;
            j = rand() % 3; // get new number and then check if it's unique
            for(int k = 0; k < 39; k++) if (used[i] == j) {unique = false; break;}
        } while(!unique);
    im->pixels[j]->r = im->pixels[j]->r & ~1 | binaryMessage[39]; // last bit
    free(binaryMessage);
    return im;
}

static int *decimalToBinary(const char *message, unsigned int length) {
    /*
     * malloc is used here instead of [] notation to allocate memory,
     * because defining the variable with [] will make its scope
     * limited to this function only. Since we want to access this
     * array later on, we use malloc to assign space in the memory
     * for it so we can access it using a pointer later on.
     */
    int k = 0, i, j;
    unsigned int c;
    unsigned int *binary = malloc(8 * length * sizeof(int));

    for(i = 0; i < length; i++) {
        c = message[i];
        for(j = 7; j >= 0; j--,k++) {
            /*
             * We check here if the jth bit of the number is 1 or 0
             * using the bit operator &. If it is 1, it will return
             * 1 because 1 & 1 will be true. Otherwise 0.
             */
            if((c >> j) & 1)
                binary[k] = 1;
            else
                binary[k] = 0;
        }
    }
    return binary;
}

我不确定为什么会这样,所以我在valgrind内部运行错误,因为我在线阅读了这是一个非常有用的调试器,但是我仍然无法理解问题的根源。这是valgrind中的错误报告:

==2066== Invalid free() / delete / delete[] / realloc()
==2066==    at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2066==    by 0x108B14: main (in /home/ziyad/test12)
==2066==  Address 0x30a060 is 0 bytes inside data symbol "ppm"
==2066== 
==2066== 
==2066== HEAP SUMMARY:
==2066==     in use at exit: 2,150,955 bytes in 515 blocks
==2066==   total heap usage: 519 allocs, 5 frees, 2,156,305 bytes allocated
==2066== 
==2066== 3 bytes in 1 blocks are still reachable in loss record 1 of 4
==2066==    at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2066==    by 0x108B4D: getPPM (in /home/ziyad/test12)
==2066==    by 0x108AC8: main (in /home/ziyad/test12)
==2066== 
==2066== 552 bytes in 1 blocks are still reachable in loss record 2 of 4
==2066==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2066==    by 0x4EBAE49: __fopen_internal (iofopen.c:65)
==2066==    by 0x4EBAE49: fopen@@GLIBC_2.2.5 (iofopen.c:89)
==2066==    by 0x108A9B: main (in /home/ziyad/test12)
==2066== 
==2066== 6,144 bytes in 1 blocks are still reachable in loss record 3 of 4
==2066==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2066==    by 0x108C0E: getPPM (in /home/ziyad/test12)
==2066==    by 0x108AC8: main (in /home/ziyad/test12)
==2066== 
==2066== 2,144,256 bytes in 512 blocks are still reachable in loss record 4 of 4
==2066==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2066==    by 0x108C53: getPPM (in /home/ziyad/test12)
==2066==    by 0x108AC8: main (in /home/ziyad/test12)
==2066== 
==2066== LEAK SUMMARY:
==2066==    definitely lost: 0 bytes in 0 blocks
==2066==    indirectly lost: 0 bytes in 0 blocks
==2066==      possibly lost: 0 bytes in 0 blocks
==2066==    still reachable: 2,150,955 bytes in 515 blocks
==2066==         suppressed: 0 bytes in 0 blocks
==2066== 
==2066== For counts of detected and suppressed errors, rerun with: -v
==2066== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Nikos C.

ppm是一个堆栈对象,而不是堆分配的对象。您不应该释放它。您只能调用free()先前由malloc()返回的指针calloc()这里不是这种情况,所以不是free()

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C:free():无效指针异常终止(核心已转储)

来自分类Dev

分段错误(核心转储)C ++-指针

来自分类Dev

异常终止(核心转储)红宝石错误

来自分类Dev

在C中使用free()时,无效(中止)核心转储错误

来自分类Dev

realloc(): 无效指针中止(核心转储)

来自分类Dev

分段错误(核心转储)-结构和指针--C语言

来自分类Dev

free():无效的指针;ld终止于信号6 [Aborted],核心已转储

来自分类Dev

C ++链表核心转储错误

来自分类Dev

分段错误(核心转储)C++

来自分类Dev

分段错误(核心转储)C

来自分类Dev

C 中的分段错误(核心转储)

来自分类Dev

基本指针使用:分段错误,核心转储

来自分类Dev

分段错误(核心转储)指针结构数据类型

来自分类Dev

如何重定向此“浮点异常(核心转储)”错误?

来自分类Dev

转储进程核心而不终止进程

来自分类Dev

转储进程核心而不终止进程

来自分类Dev

总线错误(核心转储)

来自分类Dev

段错误(核心转储)

来自分类Dev

随机错误核心转储:`./a.out'中的错误:free():下一个大小无效(快速):0x00000000010e8d70 ***中止(核心转储)

来自分类Dev

如何修复C中的分段错误(核心转储)错误

来自分类Dev

分段错误:C中的核心转储错误

来自分类Dev

C编程分段错误(核心转储)错误

来自分类Dev

C 程序错误 - 分段错误(核心转储)

来自分类Dev

使用C从核心转储获取导致分段错误的地址

来自分类Dev

实现家族树时的C ++核心转储错误

来自分类Dev

分段错误(转储核心)C ++初学者

来自分类Dev

使用C从核心转储获取导致分段错误的地址

来自分类Dev

奇怪的核心转储错误在C中的链表示例

来自分类Dev

C 中的分段错误(核心转储) - 使用 PTHREADS 时

Related 相关文章

  1. 1

    C:free():无效指针异常终止(核心已转储)

  2. 2

    分段错误(核心转储)C ++-指针

  3. 3

    异常终止(核心转储)红宝石错误

  4. 4

    在C中使用free()时,无效(中止)核心转储错误

  5. 5

    realloc(): 无效指针中止(核心转储)

  6. 6

    分段错误(核心转储)-结构和指针--C语言

  7. 7

    free():无效的指针;ld终止于信号6 [Aborted],核心已转储

  8. 8

    C ++链表核心转储错误

  9. 9

    分段错误(核心转储)C++

  10. 10

    分段错误(核心转储)C

  11. 11

    C 中的分段错误(核心转储)

  12. 12

    基本指针使用:分段错误,核心转储

  13. 13

    分段错误(核心转储)指针结构数据类型

  14. 14

    如何重定向此“浮点异常(核心转储)”错误?

  15. 15

    转储进程核心而不终止进程

  16. 16

    转储进程核心而不终止进程

  17. 17

    总线错误(核心转储)

  18. 18

    段错误(核心转储)

  19. 19

    随机错误核心转储:`./a.out'中的错误:free():下一个大小无效(快速):0x00000000010e8d70 ***中止(核心转储)

  20. 20

    如何修复C中的分段错误(核心转储)错误

  21. 21

    分段错误:C中的核心转储错误

  22. 22

    C编程分段错误(核心转储)错误

  23. 23

    C 程序错误 - 分段错误(核心转储)

  24. 24

    使用C从核心转储获取导致分段错误的地址

  25. 25

    实现家族树时的C ++核心转储错误

  26. 26

    分段错误(转储核心)C ++初学者

  27. 27

    使用C从核心转储获取导致分段错误的地址

  28. 28

    奇怪的核心转储错误在C中的链表示例

  29. 29

    C 中的分段错误(核心转储) - 使用 PTHREADS 时

热门标签

归档