0

そこで弟が文字列内の単語をすべてハッシュタグにするプログラムを作っていたのですが、なぜか実行終了時に必ず「セグメンテーション違反」のエラーが出てしまいます。原因と思われるものを探してみましたが、見つかりませんでした。コードは次のとおりです。

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

char* setHashtag(char text[10000])
{
    int i, j;

    printf("Initial text = %s\n", text);

    for (i = 9998; i >= 0; i--)
    {
        text[i+1] = text[i];
    }
    text[0] = ' ';

    for (i = 0; text[i+1] != '\0'; i++)
    {
        if(text[i] == ' ' && text[i+1] != ' ')
        {
            for (j = 9998; j > i; j--)
            {
                text[j+1] = text[j];
            }
            text[i+1] = '#';

            printf("Partial text = %s\n", text);
        }
    }

    return text;
}

void execute() {
    char text[5000], textFinal[10000];

    gets(text);

    strcpy(textFinal, setHashtag(text));
    printf("%s\n", textFinal);
}

int main()
{
    execute();
    printf("Back to main\n");
    return 0;
}
4

1 に答える 1

8

サイズの配列を5000関数に渡しますが、10000内部の要素にアクセスします。もちろん、それはクラッシュします。

関数宣言で指定する配列のこのサイズは問題ではありません。これはコンパイラによって無視されます。これ

char* setHashtag(char text[10000])

これに等しい

char* setHashtag(char *text)

つまり、関数は、引数配列の新しいローカル コピーではなく、元の引数配列の先頭へのポインターを受け取ります (C の裸の配列はコピーできません)。

これは、関数を次のように呼び出すと、

char text[5000];
...
setHashtag(text)

text配列が魔法のように配列になるわけではありませんchar [10000]char [5000]最初に宣言されたとおり、配列のままです。関数内でアクセスなどを試みるとtext[9998]、未定義の動作につながります。

setHashtag関数は size の固定サイズの配列を想定しているため、関数を次10000のように宣言することをお勧めします。

char* setHashtag(char (*text)[10000])

として配列引数を渡しますsetHashing(&text)。これにより、間違ったサイズの配列を渡すことができなくなります。関数内では、配列に としてアクセスする必要があります(*text)[i]

于 2012-12-22T15:56:15.033 に答える