C 访问越界内存时没有分段错误

C 访问越界内存时没有分段错误,c,segmentation-fault,dynamic-arrays,C,Segmentation Fault,Dynamic Arrays,我英语说得不好 因此,在我的程序中,我想将txt文件中存在的文本复制到数组中 typedef struct Chaine { char * Lachaine; int Taille_C; } Chaine ; int main (void) { Chaine *Tab_Texte=NULL; Tab_Texte=(Chaine*)malloc(sizeof(Chaine)); FILE* Texte= NULL; Texte = fopen("c

我英语说得不好

因此,在我的程序中,我想将txt文件中存在的文本复制到数组中

typedef struct Chaine
{
    char * Lachaine;
    int Taille_C;
} Chaine ;

int main (void)
{
    Chaine *Tab_Texte=NULL;
    Tab_Texte=(Chaine*)malloc(sizeof(Chaine));
    FILE* Texte= NULL;
    Texte = fopen("chaines", "r");
    fseek(Texte, 0, SEEK_END);
    Tab_Texte->Taille_C=ftell(Texte);
    fseek(Texte, 0, SEEK_SET);
    Tab_Texte->Lachaine=NULL;
    Tab_Texte->Lachaine=(char*)malloc(sizeof(char)*Tab_Texte->Taille_C);
    fread(Tab_Texte->Lachaine,sizeof(char)*(Tab_Texte->Taille_C),1,Texte);
    printf("%s",Tab_Texte->Lachaine);

return 0;
}
这里一切都很好,当我改变的时候

Tab_Texte->Lachaine=(char*)malloc(sizeof(char)*Tab_Texte->Taille_C);
与(例如)

它总是有效的,它假设向我显示一个分段错误,因为
sizeof(char)*Tab\u Texte->Taille\u C-10
sizeof(char)*Tab\u Texte->Taille\u C
短,所以比文件中的文本短


你能告诉我为什么它总是起作用吗?

它之所以总是起作用,是因为你描述的是
未定义的行为
,所以没有真正定义应该发生什么

在某些情况下,它可能导致
分段错误
,但并非总是如此。因此,您的“总是”有时确实是,但事实证明,发生
分段错误的条件并不正确

考虑对代码进行以下修复:

  • 你不应该这样做

    printf("%s",Tab_Texte->Lachaine);
    
    因为您的
    选项卡\u Texte->Lachaine
    不是以null结尾的

  • 你可以试着这样做

    fwrite(Tab_Texte->Lachaine, 1, Tab_Texte->Taille_C, stdout);
    
    但通常情况下,您不会检查代码中每一个失败时返回null的函数

    比如说

    Texte = fopen("chaines", "r");
    if (Texte == NULL)
        weAreInTroubleIfWeCall_fread_OnTexte_SoAbort();
    
    也适用于
    malloc
    ,您不需要强制执行
    malloc
    ,阅读

  • 当不再需要时,您应该
    释放
    malloc
    的结果


  • 当您读取或写入未分配给程序的内存时,将出现SEGFULT。如果误用malloc,可能不会出现segfault,这取决于底层操作系统将程序加载到内存中的方式。在这种情况下,您可能正在从自己的内存中写入或读取,但位于不同的位置,可能会覆盖其他变量。

    您所经历的被称为

    • 访问已分配的内存
    • 使用以非null结尾的字符数组作为字符串
    • 提供无效的文件指针
    所有这些都会导致未定义的行为,其副作用可能是分割错误,但不能保证

  • 在使用返回的指针之前,检查
    fopen()
    是否成功
  • null终止字符数组以将其用作字符串
  • free()
    使用结束后分配的内存
  • 不要强制转换
    malloc()
    /
    calloc()
    的返回值

  • //seg故障事件未发生的原因是 //代码使用字段的内容:Tab\u Texte->Taille\u C //哪个是文件的完整大小 //(所以没有问题,除非文件小于10字节)

    //通过正确定义struct而不是typedef来消除代码中的大量混乱

    //不要强制转换malloc(和family)返回的值

    //检查malloc返回的值以确保操作成功

    #include <stdio.h>  // fopen(), fclose(), fread(), fseek(), ftell()
    #include <stdlib.h> // exit(), EXIT_FAILURE, free(), malloc()
    
    struct Chaine
    {
        char * Lachaine;
        int Taille_C;
    };
    
    int main (void)
    {
        struct Chaine *Tab_Texte=NULL;
        if( NULL == (Tab_Texte=malloc(sizeof(struct Chaine)) ) )
        { // then, malloc failed
            perror("malloc failed");
            exit( EXIT_FAILURE );
        }
    
        // implied else, malloc successful
    
        FILE* Texte= NULL;
        if(NULL == (Texte = fopen("chaines", "r")) )
        { // then fopen failed
            perror( "fopen failed for chaines for read");
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fopen successful
    
        if( 0 != fseek(Texte, 0, SEEK_END) )
        { // then fseek failed
            perror( "fseek for end of file failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fseek successful
    
        if( -1L == (Tab_Texte->Taille_C=ftell(Texte) ) )
        { // then ftell failed
            perror("ftell failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, ftell successful
    
        if( 0 != fseek(Texte, 0, SEEK_SET) )
        { // then fseek failed
            perror( "fseek for start of file failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fseek successful
    
    
        Tab_Texte->Lachaine=NULL;
        if( NULL == (Tab_Texte->Lachaine=malloc(Tab_Texte->Taille_C) ) )
        { // then, malloc failed
            perror( "malloc failed for file size" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, malloc successful
    
        if( 1 != fread(Tab_Texte->Lachaine, sizeof(Tab_Texte->Taille_C), 1 , Texte) )
        { // fread failed
            perror( "fread for whole file failed" );
            fclose(Texte);
            free(Tab_Texte->Lachaine);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fread successful
    
        printf("%s",Tab_Texte->Lachaine);
    
        // cleanup
        fclose(Texte);
        free(Tab_Texte->Lachaine);
        free(Tab_Texte);
    
        return 0;
    } // end function: main
    
    //检查fopen返回的值以确保操作成功

    #include <stdio.h>  // fopen(), fclose(), fread(), fseek(), ftell()
    #include <stdlib.h> // exit(), EXIT_FAILURE, free(), malloc()
    
    struct Chaine
    {
        char * Lachaine;
        int Taille_C;
    };
    
    int main (void)
    {
        struct Chaine *Tab_Texte=NULL;
        if( NULL == (Tab_Texte=malloc(sizeof(struct Chaine)) ) )
        { // then, malloc failed
            perror("malloc failed");
            exit( EXIT_FAILURE );
        }
    
        // implied else, malloc successful
    
        FILE* Texte= NULL;
        if(NULL == (Texte = fopen("chaines", "r")) )
        { // then fopen failed
            perror( "fopen failed for chaines for read");
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fopen successful
    
        if( 0 != fseek(Texte, 0, SEEK_END) )
        { // then fseek failed
            perror( "fseek for end of file failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fseek successful
    
        if( -1L == (Tab_Texte->Taille_C=ftell(Texte) ) )
        { // then ftell failed
            perror("ftell failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, ftell successful
    
        if( 0 != fseek(Texte, 0, SEEK_SET) )
        { // then fseek failed
            perror( "fseek for start of file failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fseek successful
    
    
        Tab_Texte->Lachaine=NULL;
        if( NULL == (Tab_Texte->Lachaine=malloc(Tab_Texte->Taille_C) ) )
        { // then, malloc failed
            perror( "malloc failed for file size" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, malloc successful
    
        if( 1 != fread(Tab_Texte->Lachaine, sizeof(Tab_Texte->Taille_C), 1 , Texte) )
        { // fread failed
            perror( "fread for whole file failed" );
            fclose(Texte);
            free(Tab_Texte->Lachaine);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fread successful
    
        printf("%s",Tab_Texte->Lachaine);
    
        // cleanup
        fclose(Texte);
        free(Tab_Texte->Lachaine);
        free(Tab_Texte);
    
        return 0;
    } // end function: main
    
    //检查fseek返回的值以确保操作成功

    #include <stdio.h>  // fopen(), fclose(), fread(), fseek(), ftell()
    #include <stdlib.h> // exit(), EXIT_FAILURE, free(), malloc()
    
    struct Chaine
    {
        char * Lachaine;
        int Taille_C;
    };
    
    int main (void)
    {
        struct Chaine *Tab_Texte=NULL;
        if( NULL == (Tab_Texte=malloc(sizeof(struct Chaine)) ) )
        { // then, malloc failed
            perror("malloc failed");
            exit( EXIT_FAILURE );
        }
    
        // implied else, malloc successful
    
        FILE* Texte= NULL;
        if(NULL == (Texte = fopen("chaines", "r")) )
        { // then fopen failed
            perror( "fopen failed for chaines for read");
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fopen successful
    
        if( 0 != fseek(Texte, 0, SEEK_END) )
        { // then fseek failed
            perror( "fseek for end of file failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fseek successful
    
        if( -1L == (Tab_Texte->Taille_C=ftell(Texte) ) )
        { // then ftell failed
            perror("ftell failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, ftell successful
    
        if( 0 != fseek(Texte, 0, SEEK_SET) )
        { // then fseek failed
            perror( "fseek for start of file failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fseek successful
    
    
        Tab_Texte->Lachaine=NULL;
        if( NULL == (Tab_Texte->Lachaine=malloc(Tab_Texte->Taille_C) ) )
        { // then, malloc failed
            perror( "malloc failed for file size" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, malloc successful
    
        if( 1 != fread(Tab_Texte->Lachaine, sizeof(Tab_Texte->Taille_C), 1 , Texte) )
        { // fread failed
            perror( "fread for whole file failed" );
            fclose(Texte);
            free(Tab_Texte->Lachaine);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fread successful
    
        printf("%s",Tab_Texte->Lachaine);
    
        // cleanup
        fclose(Texte);
        free(Tab_Texte->Lachaine);
        free(Tab_Texte);
    
        return 0;
    } // end function: main
    
    //检查ftell返回的值以确保操作成功

    #include <stdio.h>  // fopen(), fclose(), fread(), fseek(), ftell()
    #include <stdlib.h> // exit(), EXIT_FAILURE, free(), malloc()
    
    struct Chaine
    {
        char * Lachaine;
        int Taille_C;
    };
    
    int main (void)
    {
        struct Chaine *Tab_Texte=NULL;
        if( NULL == (Tab_Texte=malloc(sizeof(struct Chaine)) ) )
        { // then, malloc failed
            perror("malloc failed");
            exit( EXIT_FAILURE );
        }
    
        // implied else, malloc successful
    
        FILE* Texte= NULL;
        if(NULL == (Texte = fopen("chaines", "r")) )
        { // then fopen failed
            perror( "fopen failed for chaines for read");
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fopen successful
    
        if( 0 != fseek(Texte, 0, SEEK_END) )
        { // then fseek failed
            perror( "fseek for end of file failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fseek successful
    
        if( -1L == (Tab_Texte->Taille_C=ftell(Texte) ) )
        { // then ftell failed
            perror("ftell failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, ftell successful
    
        if( 0 != fseek(Texte, 0, SEEK_SET) )
        { // then fseek failed
            perror( "fseek for start of file failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fseek successful
    
    
        Tab_Texte->Lachaine=NULL;
        if( NULL == (Tab_Texte->Lachaine=malloc(Tab_Texte->Taille_C) ) )
        { // then, malloc failed
            perror( "malloc failed for file size" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, malloc successful
    
        if( 1 != fread(Tab_Texte->Lachaine, sizeof(Tab_Texte->Taille_C), 1 , Texte) )
        { // fread failed
            perror( "fread for whole file failed" );
            fclose(Texte);
            free(Tab_Texte->Lachaine);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fread successful
    
        printf("%s",Tab_Texte->Lachaine);
    
        // cleanup
        fclose(Texte);
        free(Tab_Texte->Lachaine);
        free(Tab_Texte);
    
        return 0;
    } // end function: main
    
    //退出程序时进行清理,包括对malloc'd区域的免费清理、关闭文件等

    //检查fread返回的值以确保操作成功

    #include <stdio.h>  // fopen(), fclose(), fread(), fseek(), ftell()
    #include <stdlib.h> // exit(), EXIT_FAILURE, free(), malloc()
    
    struct Chaine
    {
        char * Lachaine;
        int Taille_C;
    };
    
    int main (void)
    {
        struct Chaine *Tab_Texte=NULL;
        if( NULL == (Tab_Texte=malloc(sizeof(struct Chaine)) ) )
        { // then, malloc failed
            perror("malloc failed");
            exit( EXIT_FAILURE );
        }
    
        // implied else, malloc successful
    
        FILE* Texte= NULL;
        if(NULL == (Texte = fopen("chaines", "r")) )
        { // then fopen failed
            perror( "fopen failed for chaines for read");
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fopen successful
    
        if( 0 != fseek(Texte, 0, SEEK_END) )
        { // then fseek failed
            perror( "fseek for end of file failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fseek successful
    
        if( -1L == (Tab_Texte->Taille_C=ftell(Texte) ) )
        { // then ftell failed
            perror("ftell failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, ftell successful
    
        if( 0 != fseek(Texte, 0, SEEK_SET) )
        { // then fseek failed
            perror( "fseek for start of file failed" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fseek successful
    
    
        Tab_Texte->Lachaine=NULL;
        if( NULL == (Tab_Texte->Lachaine=malloc(Tab_Texte->Taille_C) ) )
        { // then, malloc failed
            perror( "malloc failed for file size" );
            fclose(Texte);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, malloc successful
    
        if( 1 != fread(Tab_Texte->Lachaine, sizeof(Tab_Texte->Taille_C), 1 , Texte) )
        { // fread failed
            perror( "fread for whole file failed" );
            fclose(Texte);
            free(Tab_Texte->Lachaine);
            free(Tab_Texte);
            exit( EXIT_FAILURE );
        }
    
        // implied else, fread successful
    
        printf("%s",Tab_Texte->Lachaine);
    
        // cleanup
        fclose(Texte);
        free(Tab_Texte->Lachaine);
        free(Tab_Texte);
    
        return 0;
    } // end function: main
    
    #包括//fopen()、fclose()、fread()、fseek()、ftell()
    #包括//exit()、exit_FAILURE、free()、malloc()
    结构链
    {
    查尔*拉切恩;
    内特泰勒(C);
    };
    内部主(空)
    {
    结构链*Tab_Texte=NULL;
    if(NULL==(Tab_Texte=malloc(sizeof(struct Chaine)))
    {//然后,malloc失败了
    perror(“malloc失败”);
    退出(退出失败);
    }
    //否则,malloc成功了
    文件*Texte=NULL;
    if(NULL==(Texte=fopen(“链”、“r”))
    {//然后fopen失败了
    perror(“读取链的fopen失败”);
    免费(制表符);
    退出(退出失败);
    }
    //否则,fopen成功了
    如果(0!=fseek(Texte,0,SEEK_END))
    {//然后fseek失败了
    perror(“文件结尾的fseek失败”);
    fclose(Texte);
    免费(制表符);
    退出(退出失败);
    }
    //否则,fseek将成功
    如果(-1L==(Tab_Texte->Talle_C=ftell(Texte)))
    {//然后ftell失败了
    perror(“ftell失败”);
    fclose(Texte);
    免费(制表符);
    退出(退出失败);
    }
    //否则,ftell将成功
    如果(0!=fseek(Texte,0,SEEK_SET))
    {//然后fseek失败了
    perror(“文件启动的fseek失败”);
    fclose(Texte);
    免费(制表符);
    退出(退出失败);
    }
    //否则,fseek将成功
    Tab_Texte->Lachaine=NULL;
    如果(NULL==(Tab_-Texte->Lachaine=malloc(Tab_-Texte->Talle_-C)))
    {//然后,malloc失败了
    perror(“malloc文件大小失败”);
    fclose(Texte);
    免费(制表符);
    退出(退出失败);
    }
    //否则,malloc成功了
    如果(1!=fread(Tab_Texte->Lachaine,sizeof(Tab_Texte->Taille_C),1,Texte))
    {//fread失败了
    perror(“整个文件的fread失败”);
    fclose(Texte);
    免费(Tab_Texte->Lachaine);
    免费(制表符);
    退出(退出失败);
    }
    //否则,fread成功了
    printf(“%s”,制表符->文本->链接);
    //清理
    fclose(Texte);
    免费(Tab_Texte->Lachaine);
    免费(制表符);
    返回0;
    }//结束函数:main
    
    标题应为“为什么我没有得到分段错误?”。第1点。不要强制转换malloc()的返回值。第2点。如果这是
    c++
    ,建议使用
    new
    。第3点。您从未
    释放分配的内存。将导致内存泄漏。请将答案放在顶部,然后建议进行其他重要更改。:-)@SouravGhosh您的评论在哪里非常有帮助,我把这个问题理解为
    分段错误而不是o