C 访问越界内存时没有分段错误
我英语说得不好 因此,在我的程序中,我想将txt文件中存在的文本复制到数组中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
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