5

私は文字ポインタとそれらがどのように機能するかについてはあまり明確ではありません。

プログラムはビルドされますが、実行するとクラッシュします。

 char *ab = NULL;
 //ab = "abc123"; // works fine
 sprintf(ab, "abc%d", 123); // this line seems to crash the program

sprintfが最初の引数として(char * str)を取り込んだ場合、これがどのように間違っているのかわかりません。

誰かが私にこれを説明できますか?

4

6 に答える 6

16

で使用するメモリを割り当てていませんab

ab文字列定数に割り当てるため、最初の割り当ては機能します"abc123"。定数文字列のメモリは、コンパイラが代わりに提供します。このメモリを割り当てる必要はありません。

abたとえばで使用する前に、を使用しsprintfてメモリをmalloc割り当て、そのスペースをab:に割り当てる必要があります。

ab = malloc(sizeof(char) * (NUM_CHARS + 1));

次に、sprintfを使用して十分なスペースを確保している限り、作業を行いますmalloc。注:これ+ 1ヌルターミネータ用です。

abまたは、配列として宣言することで、メモリを作成できます。

char ab[NUM_CHARS + 1];

なんらかの方法でメモリを割り当てないabと、sprintf呼び出しはに書き込もうとしますがNULL、これは未定義の動作です。これがクラッシュの原因です。

于 2012-06-15T17:25:43.090 に答える
2

データにメモリを割り当てる必要があります。確かにsprintfかかりますがchar*、それはあなたのためにメモリを割り当てません。

コンパイラはコンパイル時に定義されたcharの定数テーブルにデータを自動的に割り当てるため、最初の行は正常に機能します。

于 2012-06-15T17:27:19.747 に答える
1

Java他の高級言語とは異なり、ライブラリの文字列関数の多くは、文字C列参照を設定するだけでなく、文字配列と呼ばれる事前に割り当てられたメモリのブロックを操作します。

abあなたの最初の行は、それが存在しないメモリ位置を指していると言っています。

あなたの代わりに次のいずれかを行った場合、あなたはより多くの幸運を得るでしょうchar *ab = NULL;

char ab[12];

また:

char *ab = (char*)malloc(12);
于 2012-06-15T17:28:15.843 に答える
1

あなたはこれを行うことができます

char ab[10];  //allocate memory
sprintf(ab, "abc%d", 123);
于 2012-06-15T17:28:26.530 に答える
0

「ab」はnullであり、sprintfはそれに書き込もうとしているため、最初に割り当てる必要があります。

char ab[20];

sprintf(ab, "abc%d", 123); //

また

char * ab = malloc(20); // new, whatever

sprintf(ab, "abc%d", 123); //
于 2012-06-15T17:28:44.797 に答える
0

ここで考えるべきことがいくつかあります。元の例は次のとおりです。

char *ab = NULL;
 //ab = "abc123"; // works fine
 sprintf(ab, "abc%d", 123); // this line seems to crash the program

char *ab = NULL;文字へのポインタであり、NULLに初期化されます。

ab = "abc123";のように見えない限り、うまくいったとは思いませんchar *ab = "abc123";。これはchar *ab、読み取り専用の文字列に初期化したためです。初期化はおそらくコンパイル時に行われました。

ポインタsprintf(ab, "abc%d", 123);のメモリを事前に初期化していないため、行が失敗しました。char *ab言い換えれば、あなたは次のようなことをしませんでした:

ab = malloc((sizeof(char) * 3) + 1); /* + 1 allows for null string terminator. */

問題は2つの方法のいずれかで修正できます。上記のように動的メモリを割り当てるか、文字列をcharのように固定長の配列にすることができますab[25] = {0};。通常、私は1024、256、または文字列の長さのケースのほとんどをカバーするいくつかの数値のような長さの配列を作成します。次に、配列を操作する関数にcharポインターを使用します。

于 2012-06-15T21:43:25.530 に答える