2012-04-20 8 views
2

コードは、n個の要素の1次元ベクトルをi位置だけ左に回転させると仮定しています。たとえば、n = 8およびi = 3の場合、ベクトルabcdefghはdefghabcに回転されます。以下のコードで何が問題になっています

以下は、string_reverse関数でクラッシュします。そこに何が間違っているのか分からなかった。

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

void string_reverse(char* str, int left, int right) 
{ 
    char *p1 = str + left; 
    char *p2 = str + right; 

    while (p1 < p2) 
    { 
     char temp = *p1; 
     *p1 = *p2; 
     *p2 = temp; 
     p1++; 
     p2--; 
    } 
} 


void rotate(char* str, int k) 
{ 
    int n = strlen(str); 
    string_reverse(str, 0, k - 1); 
    string_reverse(str, k, n - 1); 
    string_reverse(str, 0, n -1); 
} 


int main(int argc, char* argv[]) 
{ 
    char* string = "abcdefghijk"; 

    rotate(string, 3);  
    printf("%s",string); 
    getch(); 
    return 0; 
} 



it crashes at 

*p1 = *p2; 
+2

どのようにコンパイラを使いましたか、どのプラットフォームを実行していますか? –

+2

「クラッシュした」とはどういう意味ですか?セグメンテーション違反ですか? – Thomas

+0

これは、リテラルに代入するときに 'char *'を 'const'と宣言することが良い習慣であることを証明します。 – Joe

答えて

1

このような変数の初期化子として割り当てられたメモリは、...

char* string = "abcdefghijk"; 

...不変です。つまり、変更することはできません。書き込みを試みると、セグメンテーションが発生します。 malloc()とフレンドから割り当てられたメモリのみを変更できます。あなたは、このようなあなたの静的な文字列を非常に簡単にこれを達成することができます:

char *string = strdup("abcdefghijk"); 

strdup()機能がターゲットに元の文字列malloc()内部で、その後のコピーを呼び出します。あなたはすでに#include -ing string.hなので、strdup()関数プロトタイプは、追加コードなしですでに利用可能です。

+2

'strdup()'は非標準であることに注意してください。 –

+1

これによりメモリリークが発生します。 –

+0

確かにしました。遊んでくれてありがとう。 – larsks

5

文字列を使用してオンに操作する場合は、文字ポインタではなく実際の文字配列を使用します。リテラル読み取り専用文字列に

char string[] = "abcdefghijk"; 
6

変更

char* string = "abcdefghijk"; 

char string[] = "abcdefghijk" 

前者点、後者はそのリテラルから初期化配列である一方。

+0

読み取り専用リテラルはどういう意味ですか?なぜコンパイラはそれを読み取り専用として扱いますか? – Peter

関連する問題