2009-08-13 141 views
1

我試圖重塑strcpy的C函數,但是當我嘗試運行它,我得到這個錯誤:使用strcpy時訪問衝突?

Unhandled exception at 0x00411506 in brainf%ck.exe: 0xC0000005: Access violation writing location 0x00415760. 

*dest = *src;線出現的錯誤。這裏是代碼:

char* strcpy(char* dest, const char* src) { 
    char* dest2 = dest; 
    while (*src) { 
     *dest = *src; 
     src++; 
     dest++; 
    } 
    *dest = '\0'; 
    return dest2; 
} 

編輯:哇,那很快。下面是調用代碼(strcpy的是mystring.c定義):

#include "mystring.h" 
#include <stdio.h> 

int main() { 
    char* s = "hello"; 
    char* t = "abc"; 
    printf("%s", strcpy(s, t)); 
    getchar(); 
    return 0; 
} 
+3

你打電話給你的實施?該代碼將會有所幫助。 – Jason 2009-08-13 21:18:58

+1

男人,那是一堆快速回答。歡迎來到溢出緩衝區的世界。 :) – Craig 2009-08-13 21:22:27

+0

你是怎麼稱呼它的? – 2009-08-13 21:23:08

回答

15
char* s = "hello"; 
char* t = "abc"; 
printf("%s", strcpy(s, t)); 

編譯器將目標緩衝區s放置在只讀存儲器中,因爲它是常量。

char s[5]; 
char* t = "abc"; 
printf("%s", strcpy(s, t)); 

應該解決這個問題。這將在棧上分配目標數組,這是可寫的。

+0

謝謝。 (15個字符) – Javier 2009-08-13 21:37:30

2

之前它傳遞給你的strcpy什麼才做的DEST分配?可能性是這個問題。

+1

沒關係。就像邁克爾寫的一樣。 stuf是隻讀部分的地方。你可以在gcc AFAIKT中改變它,但我認爲改變這是一個非常糟糕的主意 – Friedrich 2009-10-21 16:00:18

7

一個明顯的潛在問題是您的輸出緩衝區沒有分配足夠的內存,或者您在dest中傳遞NULL值。 (可能不是src或者它會失敗過就行了。)

請給一個簡短而完整的程序來重現問題,我們可以檢查...

這裏的肚裏爆炸爲例我在Windows上:

#include <stdlib.h> 

char* strcpy(char* dest, const char* src) { 
    char* dest2 = dest; 
    while (*src) { 
     *dest = *src; 
     src++; 
     dest++; 
    } 
    *dest = '\0'; 
    return dest2; 
} 

void main() { 
    char *d = malloc(3); 
    strcpy(d, "hello there this is a longish string"); 
} 

注意,在這種情況下,我有一個公平的量超過實際分配的內存之前,我可能會引發程序死 - 只是「你好」沒出事,但它肯定能取決於編譯器和執行環境的各個方面。

+1

爲什麼在所有編譯的名字你是否返回dest2?調用代碼不關心返回值,「輸入」參數「d」保持高位並且乾燥。 – Craig 2009-08-13 21:28:38

+0

我只是從OP複製代碼... – 2009-08-13 21:30:37

+0

異常文本說這是一個寫訪問異常的地址是接近的代碼地址 - 所以dest是一個全局或常量在可執行文件 – Michael 2009-08-13 21:34:41

0

確保dest在調用該函數之前分配了內存。

0

可能是來電者的問題:您是否檢查了dest指針?它指向有效的東西還是僅僅是垃圾?除此之外,你至少可以做的是檢查空指針,如if(!dest ||!source){/ *在函數入口處做某事,如返回NULL或拋出異常* /}。代碼看起來不錯。不是很安全,但確定。

0

有幾個錯誤。

  1. 您不分配可容納複製字符串的返回緩衝區。
  2. 在使用* src之前,您不檢查src是否爲空
  3. 您既是在參數中獲得答案並返回值。做一個或另一個。
  4. 您可以輕鬆地溢出dest緩衝區。

祝你好運。

+0

這些「錯誤」中沒有一個適用於OP的代碼。 – hughdbrown 2009-08-13 21:35:13

3

你的strcpy()很好。您正在寫入只讀內存。請參閱此說明here

如果你這樣寫,你會被罰款:

#include "mystring.h" 
#include <stdio.h> 

int main() { 
    char s[] = "hello"; 
    char t[] = "abc"; 
    printf("%s", strcpy(s, t)); 
    getchar(); 
    return 0; 
} 
1

沒有與主程序你改造的strcpy常規,既字符數組的話的問題: 的char * s =「你好「; char * t =「abc」; 將在編譯時落入內存READ ONLY段。當你試圖在例程strcpy中寫入由s指向的內存時,並且由於它指向了READ ONLY段中的一個位置,它將被捕獲,並且你會得到一個異常。這些字符串是隻讀的!

0

有史以來的代碼開始執行(通常從主函數開始)。這裏的代碼表示執行順序。因此,當進程(執行序列)啓動時,PCB(進程控制塊)被創建,pcb完成對進程地址空間,內核堆棧,dt表等進程的信息化。

在你的代碼

char* s = "hello";
char* t = "abc";

這兩個字符串這樣的您所採取的投入。

這裏,字符串(表示雙引號),它們出現在進程地址空間的文本部分。這裏的文本部分是出現在進程地址空間和文本部分中的只具有隻讀權限的部分之一。這就是爲什麼當您嘗試修改源字符串/目標字符串時,我們絕不允許更改文本區域中存在的任何數據。所以,這就是你需要變得聰明的原因。希望你能理解。