разница в сборке gdb и amp; сборка сборочного узла [дубликат]

Activity не полностью инициализирован и готов к просмотру представлений до тех пор, пока onCreate() не будет вызван в onCreate().

Объявляйте только следующие поля:

private EditText usernameField, passwordField;
private TextView error;
private ProgressBar progress;
]

, а затем назначьте значения в onCreate:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);

    usernameField = (EditText)findViewById(R.id.username);
    passwordField = (EditText)findViewById(R.id.password);
    error = (TextView)findViewById(R.id.error);
    progress = (ProgressBar)findViewById(R.id.progress);
}

Не может быть частью проблемы, но в качестве дополнительной рекомендации, Timer запускает TimerTask на фоне нить, и этого следует избегать в этом случае. Вместо этого замените Timer на Handler, чтобы запустить его в потоке пользовательского интерфейса.

new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            Intent intent = new Intent(SplashActivity.this, LoginActivity.class);
            startActivity(intent);
            finish();
        }
}, 1500);
24
задан David 9 July 2009 в 06:55
поделиться

9 ответов

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

0
ответ дан Alex Gartrell 22 August 2018 в 11:27
поделиться

Стандарт C не определяет какой-либо макет для других автоматических переменных. В частности, он специально говорит, что для избежания сомнений,

[...] Макет хранилища для параметров [function] не указан. (C11 6.9.1p9)

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

В стандарте C не содержится упоминания single слово «стек»; вполне возможно сделать, например, реализацию C, которая не содержит стеков, выделяя каждую запись активации из кучи (хотя тогда их можно было бы понять, чтобы сформировать стек).

Одной из причин дать компилятору некоторую свободу действий является эффективность. Однако текущие компиляторы также использовали бы это для обеспечения безопасности, используя трюки, такие как рандомизация размещения адресного пространства и канальные каналы , чтобы попытаться затруднить использование неопределенного поведения . Переупорядочение буферов сделано для более эффективного использования канарейки.

1
ответ дан Antti Haapala 22 August 2018 в 11:27
поделиться

Итак, я сделал еще несколько экспериментов, и вот что я нашел. Кажется, он основан на том, является ли каждая переменная массивом. Учитывая этот вход:

void f5() {
        int w;
        int x[1];
        int *ret;
        int y;
        int z[1];
}

В итоге я получаю это в gdb:

(gdb) p &w
$1 = (int *) 0xbffff4c4
(gdb) p &x
$2 = (int (*)[1]) 0xbffff4c0
(gdb) p &ret 
$3 = (int **) 0xbffff4c8
(gdb) p &y
$4 = (int *) 0xbffff4cc
(gdb) p &z
$5 = (int (*)[1]) 0xbffff4bc

В этом случае int s и указатели обрабатываются сначала, последним объявленным в верхнюю часть стека и сначала объявили ближе к основанию. Затем массивы обрабатываются в противоположном направлении, чем раньше декларация, самая высокая в стеке. Я уверен, что для этого есть веская причина. Интересно, что это.

8
ответ дан David 22 August 2018 в 11:27
поделиться

Интересно, если вы добавите дополнительный int * ret2 в function1, тогда в моей системе порядок будет правильным, тогда как его вывести из строя только для трех локальных переменных. Я предполагаю, что это упорядочено таким образом из-за отражения стратегии распределения регистров, которая будет использоваться. Либо это, либо это произвольно.

0
ответ дан Dean Povey 22 August 2018 в 11:27
поделиться

Я понятия не имею , почему GCC организует свой стек так, как он делает (хотя, я думаю, вы можете взломать его источник или эту статью и узнать), но Я могу рассказать вам, как гарантировать порядок определенных переменных стека, если по какой-то причине вам нужно это сделать. Просто поставьте их в struct:

void function1() {
    struct {
        int x;
        int y;
        int z;
        int *ret;
    } locals;
}

Если моя память правильно меня обслуживает, spec гарантирует, что &ret > &z > &y > &x. Я оставил свой K & amp; R на работе, поэтому я не могу приводить главу и стихи.

15
ответ дан Emil Vikström 22 August 2018 в 11:27
поделиться

Обычно это связано с проблемами выравнивания.

Большинство процессоров медленнее извлекают данные, которые не выравниваются по процессорному слову.

Вероятно, что происходит, это то, что все объекты, которые больше или равны оптимальному выравниванию процессора вместе, а затем более плотно упаковывают вещи, которые не могут быть выровнены. Так получилось, что в вашем примере все ваши char массивы имеют 4 байта, но я уверен, что если вы сделаете их 3 байта, они все равно окажутся в тех же местах.

Но если вы было четыре однобайтных массива, они могут оказаться в одном 4-байтовом диапазоне или выровнены в четырех отдельных.

Это все о том, что проще (переводится как «самый быстрый») для захвата процессора.

5
ответ дан lavinio 22 August 2018 в 11:27
поделиться
  • 1
    Ну, здесь GCC выравнивает стек по 16 байт по умолчанию. Кроме того, даже если мы имели дело с выравниванием по 4 байта, массивы и целые числа имеют одинаковый размер (4 байта на кусок), поэтому я не знаю, почему вы переупорядочиваете. – David 9 July 2009 в 07:14

Это также может быть проблема безопасности?

int main()
{
    int array[10];
    int i;
    for (i = 0; i <= 10; ++i)
    {
        array[i] = 0;
    }
}

Если массив меньше в стеке, чем i, этот код будет циклически бесконечно (потому что он ошибочно обращается к нулевому массиву [10], что я). Помещая массив выше в стеке, попытки доступа к памяти за пределами стека будут чаще касаться нераспределенной памяти и сбой, а не вызывать неопределенное поведение.

Я экспериментировал с этим же кодом один раз с gcc и не смог выполнить его, за исключением конкретной комбинации флагов, которые я не помню сейчас. В любом случае он разместил массив несколько байтов от i.

0
ответ дан Nick Lewis 22 August 2018 в 11:27
поделиться
  • 1
    Скорее всего, не. Существуют защитные страницы для переполнения и переполнения стека, но ничего между кадрами стека нет. – lavinio 9 July 2009 в 07:13
  • 2
    Здесь проблема с безопасностью - это неправильный код. Да, это приводит к бесконечному циклу с одним конкретным компилятором / флагом. Но для меня это холодный комфорт. – Matthew Flaschen 9 July 2009 в 07:23
  • 3
    Интересно, что поскольку массивы определены в верхнем конце стека, вы не можете переполнять массив, чтобы перезаписать другие переменные без массива. – Dog eat cat world 23 May 2018 в 20:28

Я предполагаю, что это связано с тем, как данные загружаются в регистры. Возможно, с массивами char, компилятор работает с некоторой магией, чтобы делать что-то параллельно, и это имеет какое-то отношение к положению в памяти, чтобы легко загружать данные в регистры. Попробуйте выполнить компиляцию с различными уровнями оптимизации и попробуйте использовать int buffer1[1].

0
ответ дан rlbond 22 August 2018 в 11:27
поделиться

Не только ISO C ничего не говорит о упорядочении локальных переменных в стеке, он даже не гарантирует, что стек даже существует. Стандарт просто говорит о масштабах и времени жизни переменных внутри блока.

7
ответ дан sigjuice 22 August 2018 в 11:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: