Это безопасный способ свернуть массив C или он подвержен ошибкам сегментации? - PullRequest
1 голос
/ 12 апреля 2020

Моему приложению требуется много операций прокрутки над массивами 1d C, и сдвиг может быть любым положительным или отрицательным целым числом, чтобы он мог откатываться назад или вперед по элементам сдвига. Поскольку мне нужно много таких операций, я пытаюсь сделать это как можно более оптимальным.

Я написал эту функцию для сдвига вперед на 1 элемент:

double * myC_roll1dfront( double *ptr, int size){

        double * ptr2 = ptr - 1; //this is a critical point in this question

        *ptr2 = *(ptr+size-1);

        return ptr2;
}

и эту функцию для 1-элемента обратное смещение.

double * myC_roll1dback( double *ptr, int size){

        double * ptr2 = ptr + 1;  //this is a critical point in this question

        *(ptr+size) = *ptr;

        return ptr2;
}

Тогда в случае, если смещение больше - + 1, я называю вышеуказанное время смещения из этого:

double * myC_roll1d( double *ptr, int size, int shift){

        double * ptr2;
        double * temp = ptr;

        if (shift > 0){
                for(int i=0; i<shift; i++){
                        ptr2 = myC_roll1dfront(temp, size);
                        temp = ptr2;
                }
        }

        if (shift < 0){
                for(int i=0; i<abs(shift); i++){
                        ptr2 = myC_roll1dback(temp, size);
                        temp = ptr2;
                }
        }

        if (shift == 0) ptr2 = ptr;

        return ptr2;
}

Код работает совершенно идеально, и я думаю, что оптимальная реализация, так как она требует только операций чтения / записи смещения. Например, когда мне нужно сместить на 1 элемент, я не копирую все данные на 1 позицию назад и не добавляю первую в конец. Что я делаю, так это смещаю указатель на один шаг назад и записываю последний элемент в этой позиции, который теперь становится первой позицией.

Меня беспокоит то, что я получаю доступ к области памяти, которую не должен (double * ptr2 = ptr - 1 или здесь *(ptr+size) = *ptr;), но у меня не было ошибок сегментации.

Правильно ли мое беспокойство или мне вообще не о чем беспокоиться?

1 Ответ

0 голосов
/ 12 апреля 2020

Зависит от того, как вы используете функции. Например, это, очевидно, будет проблемой:

int arr[10] = {0};
int *p = myC_roll1dfront(arr, 10);

Поскольку ptr2 будет указывать на arr[-1]. Но назвать это так:

int arr[10] = {0};
int *p = myC_roll1dfront(&arr[1], 9);

совершенно правильно.

...