分割断层

Mah*_*sod 3 c valgrind segmentation-fault

这是我的代码:

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

void main(int arge, char *argv[])
{
    FILE *f1;
    char ch,*fn="~/lyrics/";
    strcat(fn,argv[1]);
    strcat(fn,".txt");
    if( (f1 = fopen(fn,"r"))==NULL )
    {
        printf("\nWrong filename\n%s not found",argv[1]);
        return;
    }
    while((ch=getw(f1))!=EOF)
    {
        printf("%c",ch);
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用对其进行gcc -g -o file 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)
Run Code Online (Sandbox Code Playgroud)

谁能帮帮我吗?

Goz*_*Goz 5

您在fn中没有足够的空间。通过对它进行覆盖,您将覆盖其堆栈分配的末尾并进入堆栈..因此出现分段错误。

您可以尝试以下方法:

char fn[255];
strcpy( fn, "~/lyrics/" );
strcat( fn, argv[1] );
strcat( fn, ".txt" );
Run Code Online (Sandbox Code Playgroud)

您只需要确保整个路径和文件名可以容纳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" );
Run Code Online (Sandbox Code Playgroud)

并且您已经为该字符串分配了足够的空间。只是别忘了在完成后释放它!

  • 您的回答会误导您不要说错。“ *您在fn中没有足够的空间。*”不是**不是分割失败的根本原因。根本原因是您不能将内存复制到fn指向的只读内存位置,因为“〜/ lyrics /”是不能被覆盖的字符串文字。 (2认同)

md5*_*md5 5

char *fn = "~/lyrics/";
Run Code Online (Sandbox Code Playgroud)

由于fn可能指向只读内存中的字符串,因此应将其声明fn为的指针const char

const char *fn = "~/lyrics/";
Run Code Online (Sandbox Code Playgroud)

然后您会看到有一些错误。这是一个更好的解决方案:

char fn[MAX_SIZE] = "~/lyrics/";
Run Code Online (Sandbox Code Playgroud)

MAX_SIZE是的大小"~/lyrics/",最大长度argv[1]和的长度之和".txt"