Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
分段故障-strcat_C_Segmentation Fault_Valgrind - Fatal编程技术网

分段故障-strcat

分段故障-strcat,c,segmentation-fault,valgrind,C,Segmentation Fault,Valgrind,这是我的代码: #包括 #包括 #包括 void main(内部arge,字符*argv[]) { 文件*f1; char ch,*fn=“~/lyms/”; strcat(fn,argv[1]); strcat(fn,“.txt”); 如果((f1=fopen(fn,“r”))==NULL) { printf(“\n错误的文件名\n找不到%s”,argv[1]); 返回; } 而((ch=getw(f1))!=EOF) { printf(“%c”,ch); } } 我使用gcc-g-o fi

这是我的代码:

#包括
#包括
#包括
void main(内部arge,字符*argv[])
{
文件*f1;
char ch,*fn=“~/lyms/”;
strcat(fn,argv[1]);
strcat(fn,“.txt”);
如果((f1=fopen(fn,“r”))==NULL)
{
printf(“\n错误的文件名\n找不到%s”,argv[1]);
返回;
}
而((ch=getw(f1))!=EOF)
{
printf(“%c”,ch);
}
}
我使用
gcc-g-o file.c
编译了它,编译器没有给出任何错误消息。但当我运行它时,会收到错误消息:

Segmentation fault (core dumped)
Bad permissions for mapped region at address 0x8048659 at 0x402C36B: strcat 
(in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) by 0x80484D6: main (lyrics.c:9)

有人能帮我吗?

您在fn中没有足够的空间。通过对其进行strcat,您可以覆盖其堆栈分配的末尾并将其放入堆栈中。。因此,分割错误

您可以尝试以下方法:

char fn[255];
strcpy( fn, "~/lyrics/" );
strcat( fn, argv[1] );
strcat( fn, ".txt" );
您只需确保整个路径和文件名可以容纳255个字符

或者,您可以这样做:

char* fn = NULL;
int argvLen = strlen( argv[1] );
fn = malloc( 9 + argvLen + 4 + 1 ); // Add 1 for null terminator.
strcpy( fn, "~/lyrics/" );
strcat( fn, argv[1] );
strcat( fn, ".txt" );
您已经为字符串分配了足够的空间。只是别忘了在你完成后把它释放出来

char *fn = "~/lyrics/";
因为
fn
可以指向只读内存中的字符串,所以应该将
fn
声明为指向
const char
的指针

const char *fn = "~/lyrics/";
然后你可以看到有一些错误。这里有一个更好的解决方案:

char fn[MAX_SIZE] = "~/lyrics/";

此处,
MAX\u SIZE
应为
“~/lysts/”
大小、最大长度
argv[1]
和长度
“.txt”
的总和。这种方法不可移植

如果使用
glibc
,您还可以调用
asprintf()
,它只分配您所需的内存

#include <stdio.h>

...

char * pFn = NULL;

if (-1 == asprintf(&pFn, "~/lyrics/%s.txt", argv+1);
{
  perror("asprintf()");
}
else
{
  ... /* use pFn */
}

free(pFn);

...
#包括
...
char*pFn=NULL;
如果(-1==asprintf(&pFn,“~/lyms/%s.txt”,argv+1);
{
perror(“asprintf()”);
}
其他的
{
…/*使用pFn*/
}
免费(pFn);
...

编译时添加
-Wall
。@alk不适用于me@SuiciDoga:请问,什么不起作用。它是如何失败的?@alk Still Segmentation fault您可能想阅读下面的答案,这些答案用问题的代码解释问题。@您的答案有误导性,不能说错。这是“fn中没有足够的空间”不是分段冲突的根本原因。根本原因是您无法将内存复制到只读内存位置,
fn
指向该位置,因为
“~/lysts/”
是无法覆盖的字符串文字。请注意
MAX_SIZE
0
-终止符(C-“字符串”)提供空间依赖于。字符的大小为8,字符的大小为1,终止符的大小为0。