我不是一位优秀的英语人士。
所以在我的程序中,我想将存在于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);
与(例如)
Tab_Texte->Lachaine=(char*)malloc(sizeof(char)*Tab_Texte->Taille_C - 10);
它始终有效,它假设向我显示分段错误,因为sizeof(char)*Tab_Texte->Taille_C - 10
比sizeof(char)*Tab_Texte->Taille_C
短,而不是文件中的文本。
你能告诉我为什么它总是有效吗?
答案 0 :(得分:5)
您遇到的问题称为undefined behavior。
所有这些都将导致未定义的行为,副作用可能是分段错误,但不能保证。
请
fopen()
是否成功
free()
使用结束后分配的内存。malloc()
/ calloc()
。答案 1 :(得分:3)
它始终有效的原因是因为你所描述的是undefined behavior
所以它并没有真正定义应该发生什么。
在某些情况下,它可能导致segmentation fault
,但并非总是如此。所以你总是有时候,但事实证明segmentation fault
发生的条件并不合适。
请考虑对您的代码进行以下修复:
你不应该这样做
printf("%s",Tab_Texte->Lachaine);
因为Tab_Texte->Lachaine
未终止
您可以尝试这样做
fwrite(Tab_Texte->Lachaine, 1, Tab_Texte->Taille_C, stdout);
但通常你不会检查代码中失败时返回null的每个函数。
例如
Texte = fopen("chaines", "r");
if (Texte == NULL)
weAreInTroubleIfWeCall_fread_OnTexte_SoAbort();
也适用于malloc
,您不需要投射malloc
,阅读this
当您不再需要free
时,malloc
的结果应该{{1}}。
答案 2 :(得分:1)
如果您读取或写入未分配给您的程序的内存,您将收到段错误。如果您滥用malloc,则可能无法获得段错误,具体取决于底层操作系统将程序加载到内存中的方式。在这种情况下,您可能在自己的记忆中书写或阅读,但在不同的位置,可能会覆盖其他变量。
答案 3 :(得分:1)
//没有发生seg故障事件的原因是因为 //代码正在使用字段的内容:Tab_Texte-> Taille_C //这是文件的完整大小 //(除非文件少于10个字节,否则没问题)
//通过正确定义struct而不是typedef来消除代码中的大量混乱
//不要从malloc(和family)中转换返回的值
//检查malloc返回的值以确保操作成功
//检查fopen返回的值以确保操作成功
//检查fseek返回的值以确保操作成功
//检查来自ftell的返回值以确保成功操作
//退出程序时清理,包括免费使用malloc&d; 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