2016-10-11 15 views
-1

次のコードで何が問題になっていますか? memsetはメモリのブロックへのポインタを使って処理することになっています。しかし、このコードは、セグメンテーションフォールト(コアダンプ)memsetが文字へのポインタで動作していません

#include<iostream> 
#include <cstring> 
using namespace std; 

int main(int argc, char** argv) 
{ 
    char* name = "SAMPLE TEXT"; 
    memset(name , '*', 6); 
    cout << name << endl; 
    return 0; 
} 

screenshot of the above program catching a segmentation fault

+0

ここにテキストの写真を掲載しないでください。テキストを投稿する。 – EJP

答えて

3

を言っコンソールに問題が表示されますこれは2011年以来、有効なC++コードではなく、これまでUBを持っていました。 CのUBです

C++≧11:ポインタには、constcharポインタに文字列リテラルを割り当てることはできません。

C++≧98とC:文字列リテラルを上書きすることはできません。

char name[] = "SAMPLE TEXT"; 

にコードを変更

、あなたは上書きすることができますローカル配列を持っています。

0

コードでは、文字列リテラル("SAMPLE TEXT")の内容を変更しようとしています。それは許可されていません。

7

Cから継承し、constのようなものであった日までの非常に古い下位互換性疣贅をC++で継承しました。文字列リテラルのタイプはconst char [n]ですが、コンパイラに指示する場合を除き、1990年以前のコードと互換性がある必要はありませんが、暗黙的にchar *変数を設定することができます。しかし、は、ではこのようなポインタを介して書き込むことはできません。実際のメモリは(可能な限り)読み取り専用とマークされています。オペレーティングシステムが読み取り専用メモリに書き込もうとしていることをレポートする方法が「セグメンテーションフォールト」エラーです。

言語仕様の点では、constポインタを使用してデータを書き込むことはできませんが、それを設定することはできませんでしたが、「未定義の動作」があります。コンパイラは診断を発行する必要はなく、コンパイルされた実行可能ファイルを取得した場合、何かを実行する可能性があります。 「セグメンテーションフォールト」は、ほとんどの場合、あなたのプログラムがどこかで定義されていない動作をしていることを意味します。

私は適切な設定でプログラムをコンパイルした場合、私はエラーが出るん:

$ g++ -std=gnu++11 -Wall -Werror test.cc 
test.cc: In function ‘int main(int, char**)’: 
test.cc:7:19: error: ISO C++ forbids converting a string constant to ‘char*’ 
[-Werror=write-strings] 
     char* name = "SAMPLE TEXT"; 
        ^~~~~~~~~~~~~ 

あなたは異なる設定がより適切である場合には、知っている-std=gnu++11 -Wall -WerrorすべてあなたのC++プログラムをコンパイルするのに十分なスキルを獲得するまでは、コンパイラがそれに相当するものであれば何でも構いません。 (あなたは、Unix系の風味のオペレーティングシステムを使用しているように見えるので、これらの設定作業をする必要があります。また、-gおよび/または-Oたいことがあります。)

あなたのプログラムを読み込むためにそれを変更して動作させることができ

#include <iostream> 
#include <cstring> 

int 
main() 
{ 
    char name[] = "SAMPLE TEXT"; 
    std::memset(name, '*', 6); 
    std::cout << name << '\n'; 
    return 0; 
} 

=>

$ g++ -std=c++11 -Wall -Werror test.cc 
$ ./a.out 
****** TEXT 

バグがchar *nameからchar name[]にある修正変更。私はいくつか他のものを変更しましたが、より良いスタイルを示すためだけです。これはコンパイラに書き込み可能メモリにmainへの文字列リテラルをコピーさせることです。 なぜそれはここで説明するには時間がかかりすぎるでしょう。良いC++の教科書を参照してください。

関連する問題