2015-03-06 3 views
-3

Здесь я получаю 4225440 в качестве адреса arr [0]; поскольку это целочисленный массив, адрес будет увеличен на 4, поэтому следующий будет 4225444;Указатель Концепция

Теперь

  1. , Что случится с этими адресами
  2. если поместить Мануалы один из адресов он показывает абсурдные значения, откуда он приходит.

Это код обсуждается

#include <stdio.h> 

int arr[10],i,a,*j; 
void del(int a); 

main() 
{ 
    for(i=0;i<4;i++) 
     scanf("%d",&arr[i]); 

    j=(int*)4225443; 

    for(i=0;i<4;i++) 
    { 
     printf("\n%d ",arr[i]); 
     printf(" %d ",&arr[i]); 
    } 

    printf(" %d ",*j); 
} 
+0

В зависимости от архитектуры процессора. Это может привести к сбою, например, в ARM-процессоре из-за неустановленного доступа при печати '* j'. И, конечно, если мы не знаем, что находится по адресу «4225443», невозможно сказать, даже если оно действительно. –

+0

Почему мы не можем сохранить значение arr [1] в 4225441, если arr [0] находится в 4225440 –

+0

@MatsPetersson отметим, что некоторые процессоры ARM имеют поддержку для неравномерного доступа – ouah

ответ

-2

Это напечатает значение, расположенное по адресу 4225443, если значение существует, в противном случае он будет производить исключение нарушения памяти.

+0

Я думаю, вы имеете в виду, если доступ к этому адресу памяти разрешен. Нет адреса памяти имеет значение, которое не существует. –

+0

нет даже близко. и код не пытается распечатать содержимое файла 4225443. – user3629249

+0

@ user3629249: код делает и другие вещи, но почему вы говорите, что он не пытается распечатать содержимое 4225443? – chqrlie

6
j=(int*)4225443; 
/* ... */ 
printf(" %d ",*j); 

С имеет свое слово сказать:.

(С11, 6.3.2.3p5) «Целое число может быть преобразовано в любой тип указателя, кроме как ранее указано, результат зависит от реализации , может быть неправильно выровнены, может не указывать на объект ссылочного типа и может быть ловушечным представлением ".

В вашем случае вы можете добавить, что вы также нарушаете правила псевдонимов.

0
most of the CPUs that we use today have either 
a 32bit or 64 bit wide bus between the CPU and the memory. 

Lets use the 32 bit wide bus for demonstration purposes.. 

in general, each memory access will be to read (or write) 32 bits, 
where the first address of that 32 bits will be an address 
that is evenly divisible by 32. 

In such a architecture, a 'int' will start on a address 
that is evenly divisible by 32 and be 4 bytes (32bits) long. 

in general, when the address of 'something' is NOT 
on a 32 bit address boundary 
(I.E. the address is not evenly divisible by 32) 
then the CPU will: 
for read, 
read the whole 32 bits from memory, 
starting at the 32 bit boundary,  
then, within the CPU, 
using the registers and the logic and math operations, 
extract the desired byte. 
for write, 
read the whole 32 bits from memory, 
starting at the 32 bit boundary, 
then, within the CPU, 
using the registers and logic and math operations, 
modify the desired byte, 
then write the whole 32 bits to memory 

In other words, 
accessing memory other than on 32bit boundarys is SLOW. 

Unfortunately some CPUs, 
if requested to read/write some value to/from memory 
at other than a 32 bit boundary will raise a bus error. 

regarding the 'unbelievable' value of the int 
when the second byte of the int is modified... 

A int (lets use a little endian architecture) is 4 bytes, 
aligned on a 32 bit boundary 
(I.E. the lowest address of the int is on a 32 bit boundary.) 

Lets, for example say the int contains '5' 
then its' representation in memory is 0x00,0x00,0x00,0x05 

Then the second byte (address of the int+1) is set to some value, 
for example, say 3, 
Then the int contains 0x000, 0x03, 0x00, 0x05 

now, when that int is printed, it will display: 196613 

Note: the order of the bytes in memory is somewhat different 
     for a big endian architecture.