3

教科書的なCコードです

void strcpy_new(char *s, char *t) {
    while ((*s = *t) != '\0') {
        s++;
        t++;
    }
}

int main(int argc, const char * argv[])
{

    char *s = "this is line a";
    char *t = "this is line b";
    printf("%s", s);
    strcpy_new(s, t);
    printf("%s", s);
    return 0;
}

Xcodeで実行すると、EXEC_BAD_ACCESSになりました。

4

4 に答える 4

5

EXEC_BAD_ACCESSを取得する理由は、これらの文字列リテラルが読み取り専用メモリに格納されている"this is line a"ためです。"this is line b"それに書き込もうとすると(*s = *t)は未定義の動作であり、そのためにクラッシュが発生します。

このコードを修正するには、2番目の文字列( )sを保持するのに十分な大きさになるようにメモリを割り当てる必要があります。t

    char s[] = "this is line a"; // contrived example, s and t are the same length
    char *t = "this is line b";
    strcpy_new(s, t);
于 2012-09-26T02:39:44.777 に答える
2

文字列リテラルでstrcpy_newある宛先で実行しようとしているに違いありませんchar *s

#include <string.h>

int main(int argc, char *argv[])
{
    char *a = "Some String";
    char *b = "Another string";
    strcpy(b, a);
    return 0;
}

EXEC_BAD_ACCESS を返します。ただし、次の場合は使用できません。

#include <string.h>

int main(int argc, char *argv[])
{
    char *a = "Some String";
    char b[] = "Another string";
    strcpy(b, a);
    return 0;
}

違いは、最初のケースでは、書き込み保護されている実行可能ファイルbのセクション内のメモリ ブロックを指していることです。__TEXT,__cstring,cstring_literals2 番目のケースでは、スタック上のメモリ ブロックを指します。

于 2012-09-26T02:54:13.413 に答える
1

問題は、文字列リテラルを上書きする効果が定義されていないことです。

char *s = "this is line a";
char *t = "this is line b";
strcpy_new(s, t);

stは両方ともコードのデータセクションでオフになっており、EXEC_BAD_ACCESSそれらを変更しようとすると、特定の設定でが発生します。

于 2012-09-26T02:41:34.853 に答える
1

文字列リテラルは読み取り専用です。良い答えはここにあります:http://ubuntuforums.org/showthread.php?t=357869

C の文字列リテラルは読み取り専用です。サンプル コードでは、「My string」は文字列リテラルです。

str[] 宣言は、リテラルを書き込み可能なメモリ (スタックまたはヒープ) にコピーします。したがって、プログラムは文字列を変更できます。

* 宣言は、リテラル自体へのポインターを初期化するため、読み取り専用セグメントへのポインターがあります。上書きしようとすると、SEGV が取得されます。

于 2012-09-26T03:06:10.087 に答える