質問
strcpy C 関数を再発明しようとしましたが、実行しようとすると、次のエラーが発生します。
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;
}
解決
char* s = "hello";
char* t = "abc";
printf("%s", strcpy(s, t));
それが一定であるため、コンパイラは読み出し専用メモリで、あなたの宛先バッファ、Sを置いています。
char s[5];
char* t = "abc";
printf("%s", strcpy(s, t));
この問題を修正する必要があります。これは、書き込み可能なスタックの宛先アレイを割り当てる。
他のヒント
明白な潜在的な問題は、あなたの出力バッファが十分なメモリが割り当てられていない、またはあなたが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");
}
この場合、私は死ぬためにプログラムを引き起こすことができる前にかなりの量によって実際に割り当てられたメモリを超えなければならなかったことに注意してください - ちょうど「こんにちは」クラッシュしていなかった、それは確かに、コンパイラのさまざまな側面に応じて、可能性がと実行環境ます。
あなたのstrcpy()は罰金です。あなたは、読み取り専用メモリを書いています。ここのこの記述を参照してください。
あなたはこれを書いていた場合、あなたは大丈夫だろうます:
#include "mystring.h"
#include <stdio.h>
int main() {
char s[] = "hello";
char t[] = "abc";
printf("%s", strcpy(s, t));
getchar();
return 0;
}
メインルーチン、両方の文字列で、あなたの再発明strcpyのルーチンの呼び出しに問題があります: char * S = "こんにちは"; char *トン= "ABC"; コンパイル時にセグメントのみをREADメモリに着陸する予定。あなたはルーチンstrcpyの中でsが指すメモリへの書き込みをしようとしているとして、それはREAD ONLYセグメント内の場所を指しているので、それがキャッチされ、あなたは例外を取得します。これらの文字列は読み取り専用です!
destが、それはその関数を呼び出す前に割り当てられたメモリのしていることを確認します。
、発信者とおそらく問題:あなたはのDEST のポインタをチェックしましたか?それは有効なものか、単にゴミを指していますか?それに加えて、あなたができる少なくとものような場合は、ヌルポインタのチェックです(!DEST ||!ソース){/ *リターンNULLのように、何かをするか、* /例外スロー}を関数のエントリに。コードはOKになります。非常に安全な、しかし、OKではない。
いくつかの間違いがあります。
- コピーされた文字列を保持できるリターン バッファを割り当てません。
- *src を使用する前に src が null かどうかを確認しません
- どちらもパラメータで答えを取得し、値を返そうとしています。どちらかを実行してください。
- dest バッファーは簡単にオーバーランしてしまいます。
幸運を。
ときにコードが実行を開始し、これまで(generaly、メイン関数から開始)。ここでのコードはexecution.soのシーケンス、プロセス(実行順序)が開始すると、PCB(プロセス制御ブロック)が作成されることを意味、このようなプロセスのアドレス空間、カーネルスタック、OFDTテーブルのようなプロセスについての完全なのinfromationを持つPCBます。
あなたのコード内の
のchar * S = "こんにちは";
char *トン= "ABC";
これは、あなたがこのような二つの文字列の入力を取ってきたものです。
ここでは、プロセスのアドレス空間のテキストセクションに存在している(二重引用符で囲まれたことを意味)の文字列。ここにテキストセクションは、読み取り専用の権限を持つプロセスのアドレス空間とテキストのセクションに存在している部分の一つです。それはあなたが元の文字列/宛先文字列を変更しようとしたとき、私たちはどのようなデータがテキストsetionに存在して変更することが許容できないなければならない理由です。そう、これはあなたのコードの理由は、あなたが注意する必要があるものです。あなたが理解してほしいです。