Solved

pointers, memory, simple stuff

Posted on 2004-04-07
11
371 Views
Last Modified: 2010-04-15
This isn't to accomplish anything in particular, just playing w/ stuff, really. Here's the code:

#include "stdio.h"

int main()
{
        int a = 257;

        int * pa = &a;

        int ar = (int) pa;

        printf("\n%i\n", ar);

        ar++;

        printf("\n%i\n", ar);

        char *pNewPa = (char *) ar;

        printf("%i", *pNewPa);

        return 0;
}

WHY:

Basically I just wanted to see if I could separate a primitive's memory into bytes. I start with an integer. I picked 257 because it has a 1 in the lowest and second-to-lowest order bytes, so that way if i was able to isolate the second byte, I would be sure(er) that I had done it than if I picked something under 256 and got a 0.

I first tried just incrementing the pointer: pa++;

Well, it must be smart enough to know that this is a pointer to an integer and (incorrectly) assume that I wanted the next memory space past the integer, so it incremented pa by 4 (4 byte integers). So, I did the little presto-chango there to model the pointer as an int, increment the int by 1, and put then cast that as a character pointer. Basically, I wanted to go from the base addy of the integer a up one BYTE, and get that BYTE - hence incrementing the addy by 1 instead of 4 and casting the result as a char pointer rather than another int.

I would then expect, when I printed the value @ this new location, I would get the value of the second-order byte of the integer a. In the case of 257, this would be 1:

00000000 00000000 00000001 00000001 = 257

but, i don't. i get a bus error sometimes, and sometimes i'll get an integer value, but not 1. I have seen 44, 20, and 5 so far.

what's up?
0
Comment
Question by:phavardel
11 Comments
 
LVL 12

Accepted Solution

by:
stefan73 earned 25 total points
ID: 10775964
Hi phavardel,
> i get a bus error sometimes
On many architectures, you cannot access data on odd addresses. The alignment must be the same as data size. SPARC is an example. Intel allows this, but you need additional CPU cycles.

What system do you use? Check that sizeof(int)==sizeof(int*).

Cheers,
Stefan
0
 
LVL 12

Expert Comment

by:stefan73
ID: 10775991
phavardel,
> 00000000 00000000 00000001 00000001 = 257

This depends on your system's endianess. On Intel systems, this will look like
00000001 00000001 00000000 00000000 = 257

and it also depends on what is in the next byte after the int.

Stefan
0
 
LVL 12

Expert Comment

by:stefan73
ID: 10776012
The correct way to get the single bytes within an int is to use shift and and operators:

byte 0: int & 0xff
byte 1: (int>>8) & 0xff
byte 2: (int>>16) & 0xff
byte 3: (int>>24) & 0xff

0
 
LVL 12

Expert Comment

by:andrewjb
ID: 10776755
... or cast the int* to a char*, and _then_ increment it - they you'll be looking at individual bytes.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 3

Assisted Solution

by:idt
idt earned 25 total points
ID: 10777495
#include <stdio.h>

char* toBin(char c) {
  static char out[9];
  int i;
  for (i=0;i<8;i++) {
    if((c << i)& 0x80)
      out[i]='1';
    else
      out[i]='0';
  }
  out[8]=0x00;
  return out;
}


int main (char argc, char **argv) {
  int a,i;
  char* c;

  if(argc==2) a=atoi(argv[1]);
  else a=257;
  c=(char*)&a;
  for(i=0;i<sizeof(int);i++) {
    printf("byte %u is %s\n",i,toBin(c[i]));
  }
}


This toy should demostrate the memory layout of an integer, left to right.

Daniel
0
 
LVL 1

Expert Comment

by:RajeshTN
ID: 10782224
Hi phavardel,
the result depends on whether ur system is litle endian or big endian. The most significant and least significant bytes would be chenged if endianness of the machine changes.
hence the result is unpredictable unless you know the endianness of your machine
bye
-Rajesh
0
 
LVL 1

Author Comment

by:phavardel
ID: 10785335
Okay, well, I'm a SPARCer, so I guess I can't address odd bytes.

Instead I've now tried the same code, except incrementing ar by 2. With 257, I would expect to get a 0, but I get a 1 that way. I changed it to 16842753 (2^16), so I would expect to see a 1 in the 3rd order byte but a 0 everywhere else, and I get a 0 then.

what's up now?

and SPARC is big endian
0
 
LVL 3

Expert Comment

by:idt
ID: 10785595
The program that I sent should run just fine on a SUN box
Where I perform the &0x80, the char value has been passed by value, and will be on the stack on the even byte.

Daniel
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now