3

クラスのCコードを書いています。このクラスでは、コードをコンパイルして学校のサーバー (sparc solaris マシン) で実行する必要があります。Linux x64 を実行しています。

解析する次の行があります (これは実際のコードではありませんが、プログラムへの入力です):

while ( cond1 ){ 

「while」と「cond1」を別々の文字列にキャプチャする必要があります。私はこれstrtok()を行うために使用してきました。Linux では、次の行:

char *cond = NULL;
cond = (char *)malloc(sizeof(char));
memset(cond, 0, sizeof(char));
strcpy(cond, strtok(NULL, ": \t\(){")); //already got the "while" out of the line

ただし、solaris マシンでこれを実行すると、文字列「cone1」が得られます。

私のプログラム内の他の多くのケースでは、文字列が正しくコピーされていることに注意してください。(たとえば、「while」) が正しくキャプチャされました。

ここで何が起こっているか知っている人はいますか?

4

3 に答える 3

11

この線:

cond = (char *)malloc(sizeof(char));

ストレージ用に正確に1つを割り当てchar、そこに複数をコピーします-strcpy最低限、ヌルターミネータを配置する必要がありますが、あなたの場合は、結果もstrtok同様に配置する必要があります。

別のシステムで動作する可能性がある理由は、 の実装によってmallocは、要求する実際の値に関係なく、特定の解像度 (たとえば、16 バイトの倍数) で割り当てられるためです。あなたのバッファ。しかし、あなたが試みているのは、まだ未定義の動作です。

未定義の動作が時々機能する可能性があるという事実は、そのような動作を回避する責任を決して放棄するものではありません。

結果を保存するのに十分なスペースを割り当てれば、strtok問題ありません。

これを行う最も安全な方法は、少なくとも渡す文字列と同じ大きさになるようにスペースを動的に割り当てることですstrtok。そうすれば、オーバーフローの可能性はありません(他のスレッドが背後でデータを変更する可能性がある奇妙なエッジケースを除きますが、その場合はstrtokとにかく非常に悪い選択になります).

次のようなもの(instr元の入力文字列の場合):

cond = (char*)malloc(strlen(instr)+1);

instrこれにより、 から抽出されたトークンが 内に収まることが保証されますcond

余談sizeof(char)ですが、定義上は常に 1 なので、掛ける必要はありません。

于 2010-04-16T05:29:14.917 に答える
2

cond には 1 バイトが割り当てられています。strcpy は、少なくとも 2 バイトをその割り当てにコピーしています。つまり、空き容量よりも多くのバイトを割り当てに書き込んでいます。

char *cond = malloc (1000);あなたが持っているものの代わりに使用するように修正する1つの方法。

于 2010-04-16T05:31:14.897 に答える
1

メモリを 1 文字だけ割り当てましたが、少なくとも 6 文字を格納しようとしています (終端の \0 のためのスペースが必要です)。これを解決する手っ取り早い方法は、ただ言うだけです

文字条件[128]

mallocの代わりに。

于 2010-04-16T05:31:01.370 に答える