0

I am trying to read the value at random memory location using the following c code

 main()
 {
   int a,*b;
   printf("enter the value of a");
   scanf("%d",&a);
   b=a;
   printf("%d\n%d\n",a,*b);
   getch(); 
  }

But the program is crashing when some negative values or even when zero is entered in place of variable a through scanf. What I am doing wrong? Does the pointers dont have negative values?

Sravan
  • 39
  • 7
  • You cannot read from arbitrary memory locations. Process most likely to terminate with Segmentation fault. – जलजनक Oct 11 '12 at 20:21
  • 4
    (1) Formally undefined behavior which implies a non-zero probability of nasal demons and (2) do you have permission from the OS to read that address? – dmckee --- ex-moderator kitten Oct 11 '12 at 20:21
  • 3
    So I'm curious; what did you *think* would happen? – Stephen Canon Oct 11 '12 at 20:22
  • 1
    Q: Why is this code that should seg-fault crashing? A: See the Q. – WhozCraig Oct 11 '12 at 20:22
  • No I don't understand why it is crashing...i dont know wether i had permission from os or not. – Sravan Oct 11 '12 at 20:24
  • @swetha You don't know if you have permission from the OS?? Hint: What do you think the OS is trying to tell you when it terminates your process? – WhozCraig Oct 11 '12 at 20:41
  • yes here is the error An Access violation(Segmentation Fault) raised in your program.thnkx for help..So the thing is a process is allowed to access only a part memory.not everything arbitarily @altendky pointers can be negative..just google that. – Sravan Oct 11 '12 at 20:43
  • Please pick up a good `C` book. You will learn faster and be more effective if you start with good theory and practices. [This book list will get you started](http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list). – Blastfurnace Oct 11 '12 at 20:44

6 Answers6

3

The thing is that as you are probably running on a modern, full service operating system and it provides a more complicated abstract machine than the one described in most intro to c programming books.

In particular, there are OS imposed restrictions on access to arbitrary addresses. You don't notice this when you look at addresses associated with standard variables because you do have permission to use the stack and the data segment, and the alloc family of functions takes care of making sure that you have permission to access the parts of the heap that they hand you.

So, what you are doing is accessing memory for which you do not have permission, which results in a failure called a "segmentation fault" on most OS, and that abruptly ends your program.


What can you do about it?

Allocate a big block on the heap, by calling char *p = malloc(1000000); and then find the starting and ending addresses with something like printf("start:\t%p\nend\t%p\n",(void*)p,(void*)(p+1000000)); and only entering numbers in that range.

Note that the %p specifier print specifier outputs in hexadecimal, so you probably want to enter address in the same base. The standard library function strtol will be helpful in that regard.

A more sophisticated approach would be to use your OS's API to request access permission for arbitrary address, but for some values the OS is likely to simply refuse.

dmckee --- ex-moderator kitten
  • 98,632
  • 24
  • 142
  • 234
2

I see some confusion here over just want a pointer is.

First, you ask the user for a value. This is fine. Then you assign that value as the location of the pointer b. This MAY be fine but likely not.

Think for a moment, what does *(-500) mean? What would *(0) mean?

In general you can never just take user input and use it without first checking it or manipulating it. This is one place where security breaches come from.

If you want to experiment with dereferencing memory, just hard code some values at first. Load the program up in a debugger and see what happens.

int c;
b = 500;
c = *b; // what happens?
b = 0;
c = *b; // what happens?
b = -100;
c = *b; // what happens?
Sean Perry
  • 3,776
  • 1
  • 19
  • 31
  • 1
    But asking a user for a value isn't fine. The operating system only allows a program to access it's own memory; it can't just go out into main memory and pull from any address that it pleases. Unless you're incredibly lucky at guessing where your program's memory is, you're going to end up with a segmentation fault, because you've tried to access memory that doesn't belong to you. – Greg Oct 11 '12 at 20:29
  • 1
    Very true. However, this is a valid learning exercise. This is a valid way to understand pointers. [Crashme](http://crashme.codeplex.com/) for instance and the links they point to. – Sean Perry Oct 11 '12 at 20:33
  • Wow, I get voted down for asking the original questioner to think and try things out. How else should we learn? Don't laugh, teach. We want students to try things and to experiment. Didn't you ever ask "Why?" in class? – Sean Perry Oct 11 '12 at 20:36
  • 1
    People sometimes don't like civil discussion. I upvoted you, for what it's worth. I thought the Crashme link was very interesting. – Greg Oct 11 '12 at 20:41
  • guys i have no right to vote up or down i havnt did anything for u....@Sean Perry.thnx for ur help – Sravan Oct 11 '12 at 20:49
2

Let me greatly oversimplify for you...

In almost all modern computers, with most operating systems, very little of the memory in the machine is directly addressable by your program. You can't take a pointer, point it at something, and try to read it. It will almost always fail.

There are generally three things that will go wrong:

  • The memory doesn't exist where you're pointing. Pointers can hold large range of values, and not all of them mean anything. It's like a house number in a postal address. Technically, you can put anything you want on the envelope. Only some are valid.
  • The memory exists, but isn't yours. The vast majority of memory in the computer is "owned" by the operating system and if you touch it, it will terminate your program. This is for your safety.
  • The memory you're trying to address is valid, in the right range, but not quite the right type. From the earlier example, you might have a reasonable house number but there's no house at that location. Or the address is really an apartment and just a number won't do.

In an old 8-bit computer from the 1980's with a full 64k of memory, you could just read any location you wanted to and it would be fine. Not so much anymore.

Clinton Pierce
  • 12,859
  • 15
  • 62
  • 90
1

In theory, you have permissions to read from any address within your virtual address space (e.g. 0 to 0xFFFFFFFF on a 32-bit machine). 0 and negative numbers are not a problem - once you assign them to pointers, they are casted to non-negative values.

In practice, it won't work. OS will protect itself (and you) from this - it won't let you read from address that doesn't really belong to you. That is, if you haven't allocated the memory page and haven't write something there, OS won't let you to read from there.

Moreover, you don't really own the whole address space - lower part of it is owned by kernel et al., so OS won't let you access it.

kliteyn
  • 1,917
  • 11
  • 24
0

Pointers are exclusively positive from what I have heard. 0 (the NULL pointer) is guaranteed not to point at anything and will cause the program to halt. Further, operatings systems (even hardware if I remember correctly) provide memory protection. This is why programs used to be able to crash each other but this is now much less common. When you program runs, the OS decides what memory it has access to and will throw a segfault if you try to access memory that isn't yours.

Then again, perhaps you just wanted b = &a? This would make b point to the same place as a exists and so, when you *b it would equate to the value stored in a.

altendky
  • 4,176
  • 4
  • 29
  • 39
0

As i see you declare b as pointer, hence it is wrong to do a=b. You will get segmentation fault. Pointers only shows to pointers not to values of integers, floats or chars. Alternatively you could do b = &a, which means that b shows to the memory address of a. So you could print then the value stored in the a.

thrylos
  • 1,513
  • 1
  • 10
  • 5