【问题标题】:Segmentation fault- strcat分段错误 - strcat
【发布时间】:2012-12-16 12:18:02
【问题描述】:

这是我的代码:

#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);
    }
}

我使用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)

谁能帮帮我?

【问题讨论】:

  • 编译时添加-Wall
  • @alk 不适合我
  • @SuiciDoga:拜托,什么不起作用。它是如何失败的?
  • @alk 仍然分段错误
  • 您可能想阅读下面的答案,这些答案解释了问题代码的问题。 @SuiciDoga

标签: c segmentation-fault valgrind


【解决方案1】:

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

您可以尝试以下方法:

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" );

而且你肯定已经为字符串分配了足够的空间。完成后别忘了释放它!

【讨论】:

  • 你的回答是误导不要说错。这个“你在 fn 中没有足够的空间。”是不是分割冲突的根本原因。根本原因是您无法将内存复制到fn 指向的只读内存位置,因为"~/lyrics/" 是无法覆盖的字符串文字。
【解决方案2】:
char *fn = "~/lyrics/";

因为fn 可以指向只读内存中的字符串,所以您应该将fn 声明为指向const char 的指针。

const char *fn = "~/lyrics/";

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

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

这里MAX_SIZE应该是"~/lyrics/"的大小、argv[1]的最大长度和".txt"的长度之和。

【讨论】:

  • 注意MAX_SIZE0-终止符提供空间,C-“字符串”依赖。 sizeof "~/lyrics/" 是 8 个字符加上 1 个 0-终止符。
【解决方案3】:

这种方法不可移植。

如果使用glibc,您也可以调用asprintf(),它会根据需要分配尽可能多的内存。

#include <stdio.h>

...

char * pFn = NULL;

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

free(pFn);

...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-16
    • 2020-10-05
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 2015-12-19
    相关资源
    最近更新 更多