2012-05-22 3 views
5

У меня есть простая программа, которая инициализирует массив как:Как хранится массив в памяти?

int a[]={10,20,30,40,50}; 

char *p; 

p=(char*)a; 

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

+5

Я предлагаю вам найти учебник для начинающих на С, потому что это такой вопрос, на самом деле, что C это все о. –

+0

Возможно, я что-то пропустил, но зачем вам нужно знать, хранится ли он в стеке или в куче? Вы пробовали p [0]? Возможно, вы можете задать вопрос, указав, какую проблему у вас есть, чтобы у нас была начальная точка ... – Ray

+0

Как говорит @Ray, в зависимости от того, что вы делаете, это может «не иметь значения» ... и может быть компилятором зависимые по-разному, определяемые операциями, которые вы можете выполнять, а не спецификой реализации. В любом случае, это не единственные два класса хранения ... ну, по крайней мере, на C++ (только что заметил, что это вопрос C, я мало знаю о формализации C ... у кого-то может быть более подходящая ссылка.) Тем не менее, это может быть полезно: http://www.gotw.ca/gotw/009.htm – HostileFork

ответ

19

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

  • локального массива будет (обычно) создан на стек в то время как
  • глобальный или статический массив будет (обычно) создан на ПБС/данных сегментов и
  • A динамически созданный массив будет создан на куча.
+3

+ 1 для смежных мест памяти – Habib

1

статически созданный массив будет в стеке или в .data/.bss разделов бинарным. Динамический массив (с new или malloc) будет выделен в куче.

-3

Во-первых, указатель должен иметь тип int. Массив - это всего лишь группа целых чисел, сохраненная в памяти как одно целое, но в одной строке. Целое число имеет 4 байта в памяти, так что вы можете получить доступ к каждому значению вашего массива, увеличивая указатель на 4.

int *p = (int*)a; 
for(i = 0; i < 5; i++) { 
    p += 4; 
    printf("%d ", *p); 
} 
+3

Поскольку OP говорит, что он/она хочет получить доступ к каждому байту и явно использовал указатель char * и char * cast, нет смысла говорить, что указатель должен иметь тип int. Кроме того, int не обязательно 4 байта, и очень неправильно добавлять 4 к указателю, так как addend умножается на размер int. –

6

Поскольку я не могу добавлять комментарии только еще, вот мои два цента в ответ:

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

Если вы хотите точно знать, где значения, вы всегда можете распечатать адрес:

printf("address at a[0] = %p\n", (void *)&a[0]); 
printf("address at p[0] = %p\n", (void *)&p[0]); 

где вы заметите тот же ответ. Но, тогда посмотрите на

printf("address at a[1] = %p\n", (void *)&a[1]); 
printf("address at p[1] = %p\n", (void *)&p[1]); 

Это веселое упражнение. Просто для удовольствия, запустите следующий код и посмотреть, что вы получите:

p[2] = 'a'; 
printf("a[0] is %d\n", a[0]); 
printf("a[1] is %d\n", a[1]); 
printf("p[2] is %d\n", p[2]); 
putchar(p[2]); 
+0

+1 для того, чтобы быть новым для SO и предлагать эксперименты, что является хорошим способом изучения и исследования. Тем не менее, всегда следует помнить, что компиляторы разные. Поэтому только потому, что вы наблюдаете образец в своих экспериментах, это не значит, что это «правда». Единственная «правда» заключается в формулировке спецификации, которая делает * некоторые гарантии ... но, кроме ошибок компилятора, спецификация все еще сильно опирается на костыль «неопределенного поведения». Кроме того, идиома - «два цента» (как в деньгах) ... не «два смысла», хотя это смешно. :) http://en.wikipedia.org/wiki/Undefined_behavior – HostileFork

+0

@HostileFork Ваши очки хорошо приняты. Я решил, что, как новый программист, поскольку google всегда, кажется, указывает мне на СО, я, вероятно, должен присоединиться! Хороший улов на «центах»! – NickO