1

重複の可能性:
文字列への書き込み時にセグメンテーション違反が発生するのはなぜですか?

forループで2つの文字列を連結しようとしている非常に単純なプログラムを書いています。文字列連結の最初の文字列は固定され、2 番目の文字列は関数を使用して取得されitoaます。プログラムは正常に構築されていますが、プログラムを実行しようとすると、実行できず停止します。プログラムをデバッグしたところ、デバッグ中にプログラムが文字列連結操作でスタックしていることに気付きました。以下にプログラムを掲載します。ご支援いただきありがとうございます :

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc,char *argv[])
{
    char *str="NULL" ,dec[] = "NULL";
    int i,num;

    printf("Enter a number : \n");
    scanf("%d",&num);

    for (i=0;i<num;i++)
    {   str = "test_file_num_"; 
        itoa(i,dec,10);
        strcat(str,dec);
         printf("%s\n",str);
    }
 return 0;
}
4

2 に答える 2

2

書き込みstrが間違っているため、そのメモリにアクセスして書き込むことができません。スターターに対してこれを行うchar *str="NULL"場合、単に5バイトを割り当てるだけであり(連結を開始するときにさらに必要になります)、読み取り専用メモリ(.dataにある場合もあれば.textにある場合もあります)でも行う場合があります。動作しますが、未定義の動作です。

ダイナミックメモリを使用できない場合は、代わりに次のようなことを試してください。

char str[128]="NULL"

これにより、スタックに128バイトが割り当てられます(それ以上が必要になる場合があります)。これは最善の方法ではありませんが、問題を解決するための最小の変更になります。

編集:

この行と同じ問題これは、読み取り専用メモリにある文字列リテラルをstr = "test_file_num_"; 指しています。strこれのためにそれを変更します:

strcpy(str, "test_file_num_");

これにより、文字列リテラルがスタックに割り当てられたバッファにコピーされます。

最後に、ループ内のすべてのコードを次のように置き換える必要があると思います。

printf("test_file_num_%d\n", i);
于 2013-01-14T23:10:50.177 に答える
2

char *str = "NULL";charポインタとして宣言し、読み取り専用strの文字列リテラル「NULL」のアドレスで初期化します。文字列リテラルの変更は未定義の動作であるため、でセグメンテーション違反が発生します(これは未定義の動作の兆候です)。言うまでもなく、メモリの初期割り当て('NULL'の場合は4バイト+'\ 0'= 5バイトの場合は1バイト)は、追加の文字列の連結には適合しません。strcat

代わりに、 malloc()を使用して動的にメモリを割り当てます。

char *str=(char*) malloc(100*sizeof(char));

または、必要がない場合は、前の回答で述べたように、いつでも配列を割り当てることができます。

注:メモリを動的に割り当てる場合は、データの処理が完了した後でそれをfree()することを忘れないでください。そうしないと、プログラムがメモリをリークします。動的にメモリを割り当てる方法について詳しく知りたい場合は、こちらを参照してください。

于 2013-01-14T23:11:30.193 に答える