0

I tried to pass a hexa string as an address to a function as an argument. But I don't know what address I can legally access. So I used a variable and got its address in hope that I could know the address my process can work with. But it did not work. I got segmentation fault 11. Can anybody please explain me why?

This is my code:

#include <stdio.h>

void print_something(char *s) {
    printf("I was here\n");
    while (*s) {
        printf("%c", *s);
        s++;
    }
    printf("\n");
}

int main() {
    char a = 48;
    printf("%p\n", &a);
    print_something((char *) 0x7ffeec6a1b5b);
    return 0;
}

And this is what I got when I executed it:

0x7ffee31ecb5b
I was here
Segmentation fault: 11
  • `0x7ffeec6a1b5b` is not a string (or a "hexa-string"), it is an integer. `(char*)0x7ffeec6a1b5b` is an address --- to some random place in your computer memory banks --- to which your program probably does not have access to. Try `char p[] = "foobar"; char *pp = p; printf("%p\n", (void*)pp); print_something(pp);` – pmg Jul 18 '20 at 07:08
  • Only pass an address that is _known_ to be valid, such as that to an appropriate variable, string const, malloc result.. an invalid address = undefined behavior, including but not limited to ‘crashes’: eg. char* s = “hello!”; print_something(s); – user2864740 Jul 18 '20 at 07:08
  • What exactly are you trying to do? if you want to pass the address of a variable then do it directly, `&a` in this case, and not as a hard coded constant. But you can't pass a pointer to one type, an `int *`, and then treat it as a string. Please explain what result you are trying to get. – kaylum Jul 18 '20 at 07:11
  • Are you trying to access individual bytes of an `int` object ? – M. Nejat Aydin Jul 18 '20 at 07:13
  • Sounds like you're doing trial and error C. That's a slow process. You need to read more about the basic concepts. – klutt Jul 18 '20 at 07:14
  • I'm trying to figure out whether the compiler can understand if I give a hexa-string address to a function which requires a pointer as an argument. If I pass to the function "print_something()" a value like &a. It will work. But if I pass to it a value like 0x7ffeec6a1b5b. Does it know that it is an address and accesses this memory block have this address. – Dũng Đào Xuân Jul 18 '20 at 07:24

3 Answers3

2

Can anybody please explain me why?

It's simply because the operating system told your program that it tried to access memory it's not allowed to access. You can read details about it here: What is a segmentation fault?

Unless you're writing very specific code, such as os kernels or coding embedded systems or something like that you should never use memory addresses directly. And there is no portable way to find out which addresses you can access.

klutt
  • 30,332
  • 17
  • 55
  • 95
1

"I'm trying to figure out whether the compiler can understand if I give a hexa-string address to a function which requires a pointer as an argument."

"If I pass to the function print_something() a value like &a. It will work. But if I pass to it a value like 0x7ffeec6a1b5b. Does it know that it is an address and accesses this memory block have this address?"

Dũng Đào Xuân 2 mins ago

The compiler doesn't know nor care whether a passed address value denotes a valid memory address or not. It simply checks if the assignment to the pointer is done correctly.

Also 0x7ffeec6a1b5b isn't a "hexa-string". It is an integer constant, which needs to be casted to the pointer type to be assigned:

"Pointer from integer/integer from pointer without a cast" issues

But if you later try to access this memory location with the hardcoded value by dereferencing the pointer, it invokes undefined behavior, if the address is invalid or used already (which is high-probably the case).

A segmentation fault says you that something with the memory allocation or memory access is not done correctly. The C standard does not mention segmentation faults explicitly because they are dependent upon implementation. It just classifies undefined behavior.

Memory addresses are given by the operation system usually to a requesting program.

You, as programmer, shouldn't care about where a specific object is stored exactly in the most times and you shouldn't attempt to use any specific address value in your code unless you code for an embedded system for example where you exactly can be sure for which address space you code.

So to answer you question:

Can I pass a hexa string as an address to a function as an argument in C?

Yes, of course. But doing any operations with treating that string or better integer as address will high-probably end up in undefined behavior. If it is well defined for your specific system, your program is nonetheless non-portable. So in general, it doesn't make much sense do so (exceptions excluded).


Side Note:

  • printf("%p\n", &a); is strictly seen undefined behavior, too. The argument pointer needs to be cast to void * -> ``printf("%p\n", (void*) &a);`
1

Yes, you can supply a hexadecimal number and cast it to a pointer. But the question is if you should, and (unless, maybe, if you are hacking something, under very exotic circumstances), the answer on that is absolutely not.

You get segmentation fault because you've told your process to access a virtual memory address that likely isn't even mapped in your process, and even if it is, you probably aren't allowed to access it, so the OS protects you from causing a mess and simply killing your process.

Boris Lipschitz
  • 1,514
  • 8
  • 12