2009-08-13 12 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

+1

男、それは素早い答えの束だった。オーバーランバッファの世界へようこそ。 :) – Craig

+0

どうやってそれを呼んでいますか? –

答えて

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

2

それはあなたのstrcpyに渡される前destに割り当てをやっていますか?それは問題です。

+1

それは問題ではありません。マイケルが書いたとおりです。 stufは読み取り専用セクションに置かれていました。あなたはgcc AFAIKTでそれを変更することができますが、それを変更することは本当に悪い考えです。 – Friedrich

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

+0

私はちょうどOPからコードをコピーしていました... –

+0

例外テキストは、コードアドレスに近いアドレスへの書き込みアクセス例外だと言います - destは実行可能ファイル内のグローバルまたは定数です – Michael

0

destがその関数を呼び出す前にメモリを割り当てていることを確認してください。

0

おそらく、発信者に関する問題:の宛先ポインタをチェックしましたか?それは何か有効であるかゴミだけを指していますか?それ以外に、関数エントリにif(!dest ||!source){/ *何かをする、NULLを返す、例外を投げる* /}のようなヌルポインタをチェックするのが最も簡単です。コードはOKです。それほど安全ではありませんが、OKです。

0

いくつかのエラーがあります。

  1. コピーした文字列を保持できるリターンバッファを割り当てません。
  2. * srcを使用する前にsrcがnullであるかどうかはチェックしません。
  3. パラメータで答えを取得して値を返すのは大変です。どちらか一方をしてください。
  4. destバッファを簡単にオーバーランさせることができます。

幸運。

+0

OPのコードにこれらの「エラー」のどれも該当しません。 – hughdbrown

3

あなたのstrcpy()は問題ありません。あなたは読み取り専用メモリに書き込みます。この説明を参照してくださいhere。あなたがこれを書いていた場合

、あなたは大丈夫だろう: のchar * S =こんにちは」:

#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 * t = "abc"; は、コンパイル時に読み取り専用セグメントにメモリに格納されます。ルーチンstrcpy内でsが指すメモリに書き込もうとしているときに、READ ONLYセグメント内の場所を指しているので、それが捕捉され、例外が発生します。これらの文字列は読み込み専用です!

0

実行を開始するコード(これは主にmain関数から開始します)。ここでコードは実行のシーケンスを意味します。プロセス(実行順序)が開始されると、PCB(プロセス制御ブロック)が作成され、プロセスアドレス空間、カーネルスタック、このようなテーブルのようなプロセスに関する完全な情報。

あなたのコード内の

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

これは、あなたがこのような二つの文字列の入力を取ってきたものです。

ここでは、プロセスアドレス空間のテキストセクションに存在する文字列(二重引用符で囲む)です。ここでのテキストセクションは、プロセスアドレススペースに存在するセクションの1つであり、テキストセクションは読み取り専用のアクセス許可を有するだけである。そのため、ソース文字列/宛先文字列を変更しようとすると、テキストセット内に存在するデータを変更することはできません(MUST NOT)。だから、あなたのコードがCAUTIOUSになる必要がある理由はこれです。あなたが理解して欲しいです。

関連する問題