2012-12-16 45 views
2

這是我的代碼:分割斷層strcat的

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

任何人都可以幫我嗎?

+0

編譯時添加'-Wall'。 – alk

+0

@alk不適合我 –

+0

@SuiciDoga:請,什麼是不工作。它是如何失敗的? – alk

回答

2

您在fn中沒有足夠的空間。通過深入瞭解它,你會覆蓋堆棧分配的結束並進入堆棧......因此會出現分段錯誤。

你可以嘗試,而不是執行以下操作:

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

而且你肯定已經分配的字符串足夠的空間。只要不要忘記釋放它,當你完成它!

+1

你的回答是誤導性的,不會說錯。這個「*你沒有足夠的空間fn。*」是**不是導致分割侵犯的根本原因。根本原因是你不能將內存複製到'fn'指向的只讀內存位置,因爲'「〜/ lyrics /」'是一個不能被覆蓋的字符串文字。 – alk

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

因爲fn可以點在只讀內存中的字符串,你應該聲明fn爲指針const char

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

然後你可以看到有一些錯誤。這裏是一個更好的解決方案:

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

這裏MAX_SIZE應的"~/lyrics/"大小,argv[1]最大長度和".txt"長度的總和。

+0

注意'MAX_SIZE'爲'0'結束符提供空間,一個C-「字符串」依賴。 'sizeof''「〜/ lyrics /」'是字符加8,'0'-終止符是1。 – alk

1

這種方法不便攜。

如果使用glibc,也可以調用asprintf(),它只是根據需要分配儘可能多的內存。

#include <stdio.h> 

... 

char * pFn = NULL; 

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

free(pFn); 

...