Почему указатели не расположены в стеке? - PullRequest
3 голосов
/ 27 октября 2009
void main(){
    int i,k;
    char* p;
    int j;
    printf("address of i is %d \naddress of k is %d \naddress of p is %p\naddress of j is %d", &i,&k,&p,&j);

}

когда я попробовал вышеуказанный код, адрес j на 4 единицы ниже k. Но адрес р не где близко. Поскольку указатель является целочисленной переменной, которая может хранить 4 байта данных, почему он не выделяется в стеке, как остальные три переменные?

Ответы [ 7 ]

13 голосов
/ 27 октября 2009

Используйте %p для печати всех адресов.

Спойлер: - это в стеке.

11 голосов
/ 27 октября 2009

Вы должны опубликовать вывод, который вы получаете. Я подозреваю, что вы немного запутались, потому что большинство печатаемых адресов отображаются в десятичном виде (с использованием% d), а p отображается в шестнадцатеричном (с использованием% p).

6 голосов
/ 27 октября 2009

Я только что попробовал ваш код на моем компьютере (под управлением Ubuntu 9.04) и получил следующее:

address of i is 0xbf96fe30
address of k is 0xbf96fe2c
address of p is 0xbf96fe28
address of j is 0xbf96fe24

после некоторого изменения кода:

void main(){
    int i,k;
    char* p;
    int j;
    printf("address of i is %p \naddress of k is %p \naddress of p is %p\naddress of j is %p\n", &i,&k,&p,&j);

}

Так как все, что вы printf () - это адреса, вы должны использовать% p вместо% d. Может быть, вы неверно истолковали свои результаты?

0 голосов
/ 20 июля 2012

Не могу не сказать вам, что ваша программа - одна из тех, которые "должны иметь отступ в шесть футов и покрываться грязью" (Google для того, кто сказал это, когда и почему :-) Это яркий пример небрежности по следующим причинам, большинство из которых вызывают неопределенное поведение:

  • Использует printf без включения stdio.h
  • Использует void main
  • Использует% d для адресов
  • Использует% p с чем-то отличным от ptr-to-void

Правильно написано, это выглядит так:

#include <stdio.h>

int main (void)
{
    int i, k;
    char *p;
    int j;

    printf ("address of i is %p\n", (void *)&i);
    printf ("address of k is %p\n", (void *)&k);
    printf ("address of p is %p\n", (void *)&p);
    printf ("address of j is %p\n", (void *)&j);
    return 0;
}
0 голосов
/ 26 ноября 2011

В конце указатель является переменной. Что касается архитектуры Linux, очень ясно, что

Все те переменные, чья память локализована для функции, останутся в стеке. <</p>

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

0 голосов
/ 27 октября 2009

Указатели могут или не могут быть расположены в стеке, поскольку они также являются своего рода переменными. Обратите внимание, что это некоторые не очень большие переменные. Если CPU / MCU имеет много регистров и компилятор хорошо оптимизирует, вы можете не увидеть указатель на стек, он вполне может провести всю свою жизнь в регистрах.

0 голосов
/ 27 октября 2009

Когда вы используете спецификатор %d printf(), вы получаете адрес, напечатанный как десятичное число, а когда вы используете спецификатор %p, вы получаете его как шестнадцатеричное число. Просто так получилось, что шестнадцатеричное число не содержит букв, и вы его неверно истолковали.

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