Аргументы против статического указателя на int - PullRequest
2 голосов
/ 29 января 2012

Я собираюсь отлаживать чужой код, и я наткнулся на определенный «способ» обработки глобальных массивов, который я считаю глубоко плохим, но тот, кто первым использовал его, клянется в этом. Мне нужно найти аргументы против этого. Вот код, написанный упрощенно (это не оригинальный код, просто абстрагированная версия)

Итак, мой вопрос: какие аргументы вы бы выдвинули (или, может быть, какой-то код, приводящий к этому методу)?

int test(int i, int v, int type, int** t)
{
    static int *teeest;
    int result = 0;
    switch(type)
    {
        case (1):
            {
                int testarr[i];
                teeest = testarr;
            }
        break;
        case (2):
            result = teeest[i];
        break;
        case (3):
            teeest[i] = v;
        break;
    }
    if (t != NULL)
    {
        *t = teeest;
    }
    return result;
}

int main()
{
    int *te = (int*)1;
    test(5, 0, 1, &te);
    printf("%p\n", te);
    int i=0;
    for(;i<5;i++)
    {
        test(i, i, 3, NULL);
        printf("Value: %d\n", test(i,0,2, NULL));
    }
    return 0;
}

Ответы [ 4 ]

3 голосов
/ 29 января 2012

локальные переменные не работают после блока, в котором они были объявлены, поэтому этот код имеет неопределенное поведение.Как и любой доступ к произвольному адресу, он может работать, но он также может не работать.

Обратите внимание, что если вы используете malloc вместо int testarr[i], (и беспокоитесь об освобождении предыдущего массива и инициализации teeest), это будет правильно.проблемы этого кода не имеют ничего о статических указателях.

2 голосов
/ 29 января 2012

Мне кажется, что большим недостатком этого стиля является то, что вы скрываете тот факт, что обращаетесь к локально объявленному массиву, который находится в стеке.Затем вы сохраняете указатель на свой стек, который будет сохраняться через вызовы, которые будут иметь разные стеки при каждом вызове.

Еще одна вещь, о которой я думал, это то, что вы скрыли от разработчика, что такое структура данных.Индексирование массива является нормальной операцией.Индексирование указателя заставляет разработчика признать, что это массив, а не более сложный тип данных.Это также добавляет путаницу к проверке границ.

2 голосов
/ 29 января 2012

Это действительно плохо. Тот факт, что указатель является статическим, не означает, что данные, на которые он указывает, будут вокруг. Например, testarr исчезает при выходе из функции, и возвращаемый указатель, если он используется, может вызвать появление драконов.

1 голос
/ 29 января 2012

Другое дело, что все недостатки глобальных переменных применяются напрямую. Код не является реентерабельным, и его трудно сделать потокобезопасным (если это важно).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...