简体   繁体   English

大小为8 2的无效读/写

[英]Invalid read/write of size 8 2

While working on my school project I keep receiving following error from Valgrind after compiling my project on Unix school server and being unable to run the program, as I receive "Segmentation fault: 11". 在我的学校项目上工作时,在Unix学校服务器上编译我的项目并且无法运行该程序后,我不断收到Valgrind的以下错误,因为我收到“ Segmentation fault:11”。

==95183== Memcheck, a memory error detector
==95183== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==95183== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==95183== Command: ./Euler
==95183==
==95183== Invalid read of size 8
==95183==    at 0x400B65: GInit (Euler.c:64)
==95183==    by 0x400DD1: main (Euler.c:118)
==95183==  Address 0x1786100 is 0 bytes after a block of size 48 alloc'd
==95183==    at 0x100688B: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==95183==    by 0x400A80: GInit (Euler.c:43)
==95183==    by 0x400DD1: main (Euler.c:118)
==95183==
==95183== Invalid write of size 4
==95183==    at 0x400B6B: GInit (Euler.c:64)
==95183==    by 0x400DD1: main (Euler.c:118)
==95183==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==95183==
==95183==
==95183== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==95183==  Access not within mapped region at address 0x0
==95183==    at 0x400B6B: GInit (Euler.c:64)
==95183==    by 0x400DD1: main (Euler.c:118)
==95183==  If you believe this happened as a result of a stack
==95183==  overflow in your program's main thread (unlikely but
==95183==  possible), you can try to increase the size of the
==95183==  main thread stack using the --main-stacksize= flag.
==95183==  The main thread stack size used in this run was 16777216.
==95183==
==95183== HEAP SUMMARY:
==95183==     in use at exit: 32,981 bytes in 16 blocks
==95183==   total heap usage: 16 allocs, 0 frees, 32,981 bytes allocated
==95183==
==95183== LEAK SUMMARY:
==95183==    definitely lost: 0 bytes in 0 blocks
==95183==    indirectly lost: 0 bytes in 0 blocks
==95183==      possibly lost: 0 bytes in 0 blocks
==95183==    still reachable: 32,981 bytes in 16 blocks
==95183==         suppressed: 0 bytes in 0 blocks
==95183== Reachable blocks (those to which a pointer was found) are not shown.
==95183== To see them, rerun with: --leak-check=full --show-reachable=yes
==95183==
==95183== For counts of detected and suppressed errors, rerun with: -v
==95183== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault: 11
eva ~/Algoritmy/Euler> make
gcc -Wall -std=c99 -pedantic -lm -g -o Euler Euler.c
eva ~/Algoritmy/Euler> ./Euler
Segmentation fault: 11 (core dumped [obraz paměti uložen])
eva ~/Algoritmy/Euler>  valgrind --leak-check=yes ./Euler
==96649== Memcheck, a memory error detector
==96649== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==96649== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==96649== Command: ./Euler
==96649==
==96649== Invalid read of size 8
==96649==    at 0x400BF2: GInit (Euler.c:85)
==96649==    by 0x400ECB: main (Euler.c:152)
==96649==  Address 0x1786100 is 0 bytes after a block of size 48 alloc'd
==96649==    at 0x100688B: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==96649==    by 0x400A8E: GInit (Euler.c:44)
==96649==    by 0x400ECB: main (Euler.c:152)
==96649==
==96649== Invalid write of size 4
==96649==    at 0x400BF8: GInit (Euler.c:85)
==96649==    by 0x400ECB: main (Euler.c:152)
==96649==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==96649==
==96649==
==96649== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==96649==  Access not within mapped region at address 0x0
==96649==    at 0x400BF8: GInit (Euler.c:85)
==96649==    by 0x400ECB: main (Euler.c:152)
==96649==  If you believe this happened as a result of a stack
==96649==  overflow in your program's main thread (unlikely but
==96649==  possible), you can try to increase the size of the
==96649==  main thread stack using the --main-stacksize= flag.
==96649==  The main thread stack size used in this run was 16777216.
==96649==
==96649== HEAP SUMMARY:
==96649==     in use at exit: 32,981 bytes in 16 blocks
==96649==   total heap usage: 16 allocs, 0 frees, 32,981 bytes allocated
==96649==
==96649== LEAK SUMMARY:
==96649==    definitely lost: 0 bytes in 0 blocks
==96649==    indirectly lost: 0 bytes in 0 blocks
==96649==      possibly lost: 0 bytes in 0 blocks
==96649==    still reachable: 32,981 bytes in 16 blocks
==96649==         suppressed: 0 bytes in 0 blocks
==96649== Reachable blocks (those to which a pointer was found) are not shown.
==96649== To see them, rerun with: --leak-check=full --show-reachable=yes
==96649==
==96649== For counts of detected and suppressed errors, rerun with: -v
==96649== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault: 11

I seem to be incorrectly allocating memory when using malloc. 使用malloc时,我似乎分配了错误的内存。 I am aware of not freeing the memory, as I haven't yet implemented a delete function. 我知道没有释放内存,因为我还没有实现删除功能。 I have added some extra testing for malloc, fgets and fscanf to eliminate the possible error. 我为malloc,fgets和fscanf添加了一些额外的测试,以消除可能的错误。 Function GInit should read formatted data from file Graph1.txt and create a graph made up of nodes. GInit函数GInit文件Graph1.txt读取格式化的数据,并创建一个由节点组成的图。 File contains number of nodes and an incidence matrix. 文件包含节点数和关联矩阵。

Here is my code: 这是我的代码:

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

#define MAXFILENAME 20

typedef struct tNode{
    int Deg;
    int Val;    
    int* Neigh; 
} *tNodePtr;

typedef struct tGraph{
    int Num;    
    tNodePtr* Nodes;    
} *tGraphPtr;


void GInit(tGraphPtr G, const char *FNum)
{
    char FileName[MAXFILENAME];
    char *FileNamePrefix = "Graph";
    char *FileNamePostfix = ".txt";
    FILE *FilePtr;
    int FileBrowser;
    int i, j, k, countNeigh;
    char *line;
    char c;

    strcpy(FileName, FileNamePrefix);
    strcat(FileName, FNum);
    strcat(FileName, FileNamePostfix);

    FilePtr = fopen(FileName, "r");

    if(!FilePtr)
        printf("Can't open file \"%s\"\n", FileName);
    else
    {
        if(!fscanf(FilePtr, "%d", &FileBrowser))
            printf("fscanf error 1!\n");

        G->Num = FileBrowser;
        G->Nodes = malloc(G->Num * sizeof *(G->Nodes));
        if(G->Nodes == NULL)
        {
            printf("Memory allocation error 1!\n");
            return;
        }

        for(i = 0; i < G->Num; i++)
        {
            G->Nodes[i] = malloc(sizeof *(G->Nodes[i]));
            if(G->Nodes[i] == NULL)
            {
                printf("Memory allocation error 2!\n");
                return;
            }
        }

        line = malloc((2*G->Num + 1) * sizeof *line );
        if(line == NULL)
        {
            printf("Memory allocation error 3!\n");
            return;
        }


        i = 0;
        if(!fscanf(FilePtr, "%c", &c))
            printf("fscanf error 2!\n");
        if(fgets(line, 2*G->Num + 1, FilePtr) == NULL)
            printf("fgets error 1!\n"); 
        while(!feof(FilePtr))
        {
            countNeigh = 0;
            j = 0;
            while(line[j] != '\0')
            {
                if(line[j] == '1')
                    countNeigh++;
                j++;
            }

            G->Nodes[i]->Deg = countNeigh;
            G->Nodes[i]->Val = i;
            G->Nodes[i]->Neigh = malloc(countNeigh * sizeof *(G->Nodes[i]->Neigh));
            if(G->Nodes[i]->Neigh == NULL)
            {
            printf("Memory allocation error 4!\n");
            return;
            }


            j = 0;
            k = 0;
            while(line[j] != '\0')
            {
                if(line[j] == '1')
                {
                    G->Nodes[i]->Neigh[k] = j/2;
                    k++;
                }
                j++;
            }

            i++;    
            if(fgets(line, 2*G->Num + 1, FilePtr) == NULL)
                if(i < G->Num)
                    printf("fgets error 2!\n"); 
        }

        free(line);
    }

    fclose(FilePtr);
}

void GPrint(const tGraphPtr G)
{
    int j, k;

    printf("Graph demonstration:\n");
    for(j = 0; j < G->Num; j++)
    {
        printf("I'm Node: %d , my degree is: %d and my neighbours are:\t", G->Nodes[j]->Val, G->Nodes[j]->Deg);
        for(k = 0; k < G->Nodes[j]->Deg; k++)
            printf("%3d", G->Nodes[j]->Neigh[k]);
        printf("\n");
    }
}

void GDelete(tGraphPtr G)
{

}

int main(int argc, char *argv[])
{

    tGraphPtr TmpGraph;
    char *FNum;
    FNum = "1";

    TmpGraph = malloc(sizeof *TmpGraph);
    if(TmpGraph == NULL)
    {
        printf("Memory allocation error 5!\n");
        return -1;
    }

    GInit(TmpGraph, FNum);

    GPrint(TmpGraph);


    return(0);  
}

Here is file Graph1.txt I am reading from. 这是我正在读取的文件Graph1.txt The file contains a newline character on the end. 该文件的末尾包含换行符。

6
0 1 0 1 0 0
1 0 1 0 1 1
0 1 0 1 1 1
1 0 1 0 0 0
0 1 1 0 0 0
0 1 1 0 0 0

Any advice how to fix this error is appreciated. 任何建议如何解决此错误表示赞赏。 BTW Microsoft VS2013 succesfully build this code (when using typecast before malloc) and runs with no error. 顺便说一句,Microsoft VS2013成功构建了此代码(在malloc之前使用类型转换的情况下)并且运行无误。 Thank you. 谢谢。 John 约翰

Did you try removing the newline from the last line of 'Graph.txt' and running the binary? 您是否尝试过从“ Graph.txt”的最后一行中删除换行符并运行二进制文件?

Also, you SHOULD do something about the leaks reported by valgrind. 另外,您应该对valgrind报告的泄漏进行处理。 Check this modified code 检查此修改后的代码

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

#define MAXFILENAME 20

typedef struct tNode{
        int Deg;
        int Val;
        int* Neigh;
} *tNodePtr;

typedef struct tGraph{
        int Num;
        tNodePtr* Nodes;
} *tGraphPtr;


void GInit(tGraphPtr G, const char *FNum)
{
        char FileName[MAXFILENAME];
        char *FileNamePrefix = "Graph";
        char *FileNamePostfix = ".txt";
        FILE *FilePtr;
        int FileBrowser;
        int i, j, k, countNeigh;
        char *line;
        char c;

        strcpy(FileName, FileNamePrefix);
        strcat(FileName, FNum);
        strcat(FileName, FileNamePostfix);

        FilePtr = fopen(FileName, "r");

        if(!FilePtr)
                printf("Can't open file \"%s\"\n", FileName);
        else
        {
                if(!fscanf(FilePtr, "%d", &FileBrowser))
                        printf("fscanf error 1!\n");

                G->Num = FileBrowser;
                G->Nodes = calloc(G->Num , sizeof *(G->Nodes));
                if(G->Nodes == NULL)
                {
                        printf("Memory allocation error 1!\n");
                        return;
                }

                for(i = 0; i < G->Num; i++)
                {
                        G->Nodes[i] = malloc(sizeof *(G->Nodes[i]));
                        if(G->Nodes[i] == NULL)
                        {
                                printf("Memory allocation error 2!\n");
                                return;
                        }
                }

                line = malloc((2*G->Num + 1) * sizeof *line );
                if(line == NULL)
                {
                        printf("Memory allocation error 3!\n");
                        return;
                }


                i = 0;
                if(!fscanf(FilePtr, "%c", &c))
                        printf("fscanf error 2!\n");
                if(fgets(line, 2*G->Num + 1, FilePtr) == NULL)
                        printf("fgets error 1!\n");
                while(!feof(FilePtr))
                {
                        countNeigh = 0;
                        j = 0;
                        while(line[j] != '\0')
                        {
                                if(line[j] == '1')
                                        countNeigh++;
                                j++;
                        }
                        G->Nodes[i]->Deg = countNeigh;
                        G->Nodes[i]->Val = i;
                        G->Nodes[i]->Neigh = malloc(countNeigh * sizeof *(G->Nodes[i]->Neigh));
                        if(G->Nodes[i]->Neigh == NULL)
                        {
                                printf("Memory allocation error 4!\n");
                                return;
                        }


                        j = 0;
                        k = 0;
                        while(line[j] != '\0')
                        {
                                if(line[j] == '1')
                                {
                                        G->Nodes[i]->Neigh[k] = j/2;
                                        k++;
                                }
                                j++;
                        }

                        i++;
                        if(fgets(line, 2*G->Num + 1, FilePtr) == NULL)
                                if(i < G->Num)
                                        printf("fgets error 2!\n");
                }

                free(line);
        }

        fclose(FilePtr);
}

void GPrint(const tGraphPtr G)
{
        int j, k;
        int i;

        printf("Graph demonstration:\n");
        for(j = 0; j < G->Num; j++)
        {
                printf("I'm Node: %d , my degree is: %d and my neighbours are:\t", G->Nodes[j]->Val, G->Nodes[j]->Deg);
                for(k = 0; k < G->Nodes[j]->Deg; k++)
                        printf("%3d", G->Nodes[j]->Neigh[k]);
                printf("\n");
        }

        for(i = 0; i < G->Num; i++)
        {
                free (G->Nodes[i]->Neigh);
                free (G->Nodes[i]);
        }

        free (G->Nodes);
}

void GDelete(tGraphPtr G)
{

}

int main(int argc, char *argv[])
{

        tGraphPtr TmpGraph;
        char *FNum;
        FNum = "1";

        TmpGraph = malloc(sizeof *TmpGraph);
        if(TmpGraph == NULL)
        {
                printf("Memory allocation error 5!\n");
                return -1;
        }

        GInit(TmpGraph, FNum);

        GPrint(TmpGraph);

        free (TmpGraph);

        return(0);
}

The o/p with valgrind 使用valgrind的o / p

[sourav@localhost ~]$ gcc -g so_test1.c -o test
[sourav@localhost ~]$ valgrind --leak-check=full ./test 
==23941== Memcheck, a memory error detector
==23941== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==23941== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==23941== Command: ./test
==23941== 
Graph demonstration:
I'm Node: 0 , my degree is: 2 and my neighbours are:      1  3
I'm Node: 1 , my degree is: 4 and my neighbours are:      0  2  4  5
I'm Node: 2 , my degree is: 4 and my neighbours are:      1  3  4  5
I'm Node: 3 , my degree is: 2 and my neighbours are:      0  2
I'm Node: 4 , my degree is: 2 and my neighbours are:      1  2
I'm Node: 5 , my degree is: 2 and my neighbours are:      1  2
==23941== 
==23941== HEAP SUMMARY:
==23941==     in use at exit: 0 bytes in 0 blocks
==23941==   total heap usage: 16 allocs, 16 frees, 533 bytes allocated
==23941== 
==23941== All heap blocks were freed -- no leaks are possible
==23941== 
==23941== For counts of detected and suppressed errors, rerun with: -v
==23941== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 8)
[sourav@localhost ~]$

Well, my Graph.txt DOES NOT have a newline at the end. 好吧,我的Graph.txt结尾没有换行符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM