Get address of a string-constant in C - c

I would like to get the address of an string-constant in C.
char * const MYCONST = "StringString";
As far as I know consts are "saved" in the Text/Code Segment of the memory.
When I try to get the address of the first element in MYCONSt:
printf("%p\n",&(MYCONST));
As result I get 0x7fff15342e28, which is in the stack and not in the Text/Code segement.
Can anybody please help me get the address of a string-constant in C?
//edit
I can't find the correct answer so far: When I write
char * const MYCONST1 = "StringString";
printf("Address of MYCONST1: %p\n",MYCONST1);
char * const MYCONST2 = "StringString";
printf("Address of MYCONST2: %p\n",(void*)MYCONST2);
this is the output:
Address of MYCONST1: 0x400b91
Address of MYCONST2: 0x400b91
But they should have different addresses, because the are different constants.
Can anybody explain me while the result has a length of seven and not 0x7fffa5dd398c like a locale variable.
Thanks!

Since MYCONST is already a pointer, you do not need an ampersand. All you need is a cast to void* for the %p:
printf("%p\n",(void*)MYCONST);
With an ampersand, you print the address of the MYCONST local variable (you need a void* cast there as well, otherwise the address may print incorrectly), which is indeed located on the stack.

printf("%p\n",(void *) &MYCONST);
prints the address of the MYCONST pointer variable.
printf("%p\n", (void *) MYCONST);
prints the value of the MYCONST pointer variable.

Q: //edit I can't find the correct answer so far: When I write
char * const MYCONST1 = "StringString";
printf("Address of MYCONST1: %p\n",MYCONST1);
char * const MYCONST2 = "StringString";
printf("Address of MYCONST2: %p\n",(void*)MYCONST2);
this is the output:
Address of MYCONST1: 0x400b91
Address of MYCONST2: 0x400b91
But they should have different addresses, because the are different constants.
A: Since both the pointers point to same string literal. Compiler optimizes and let them share the same data and hence same address. Try compiling your code with
gcc program_name.c -O
and see. You will see the addresses different.
Relative: Addresses of two pointers are same

Address of the first character of a C string is in the variable of the string itself, i.e. MYCONST in your case.

char * const MYCONST = "StringString";
initializes a pointer MYCONST, making it point to the memory where this string literal is stored.
To print an address of this string, use the pointer's value:
printf("%p\n", (void*) MYCONST);
instead of
printf("%p\n", (void*) &MYCONST);
which prints the address of pointer itself.

printf("%p\n",(void*)MYCONST);
Will print the address of the first element of string MYCONST points to.
The reason I didn't put & before MYCONST is because MYCONST is already a pointer.
If you need to print the address of Pointer, then you need to do like &MYCONST.

Related

Is passing pointer by value or by reference the same

What is the difference between passing a pointer by reference and passing a pointer by value in C?
My understanding is when you pass arguments to methods a new stack frame is created and those values are copied to different memory addresses unless passed by reference. If passed by reference the memory addresses are passed.
When working with pointers I noticed that if I pass a char* by value and modify it in a different stack frame when I return back to the main stack frame the value of the ptr has been modified.
I wrote short code to show what I am talking about.
//test pointer ref
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void passbyval(char const *lit,char* str){
printf("---passbyval---\n");
printf("%s\t%p\n",lit,&lit);
//modify string
strncat(&str[2],"/",1);
printf("%s\t%p\n",str, &str);
}
void passbyref(char const **lit, char** str){
printf("---passbyref---\n");
printf("%s\t%p\n",*lit,&*lit);
//modify string
strncat(&(*str)[1],"/",1);
printf("%s\t%p\n",*str,&*str);
}
int main(){
char const *litstr = "hello this is a test";
char *str = (char*)malloc(sizeof(char)*100);
scanf("%[^\n]",str);
printf("---main---\n");
//print original value and address
printf("%s\t%p\n",litstr,&litstr);
printf("%s\t%p\n",str,&str);
passbyval(litstr,str);
//modified value and address from pass by value
printf("\nretfromval:%s\t%p\n",str,&str);
passbyref(&litstr,&str);
//modified value and address from pass by ref
printf("\nretfromref:%s\t%p\n",str,&str);
free(str);
return EXIT_SUCCESS;
}
Output
Is it good practice to not pass by reference char* you want to modify in void methods?
Scratching my head on why I would ever use pass by reference for pointers if the value they are referencing are implicitly passed by reference.
Maybe I'm missing something can some explain this a little better?
When working with pointers I noticed that if I pass a char* by value and modify it in a different stack frame when I return back to the main stack frame the value of the ptr has been modified.
None of your examples do this. Also, none of your code prints the value of litstr or str. To print the values of the pointers, remove the & in all of your printf calls. Then you will see the values of the pointers are the same in the calling routine and the called routine.
In main, printf("%s\t%p\n",litstr,&litstr); prints:
the string that starts in memory at the address that is the value of litstr (because of %s and litstr) and
the address (not the value) of litstr (because of %p and &litstr).
Similarly, printf("%s\t%p\n",str,&str); prints the string at str and the address of str.
In passbyval, printf("%s\t%p\n",lit,&lit); prints the string at lit and the address of lit. Since lit is a parameter to passbyval, it has its own address, which is different from the address of litstr. If you had printed the values of litstr and lit, instead of their addresses, you would see they are the same.
Similarly, printf("%s\t%p\n",str, &str); prints the string at str and the address of str. The address of the parameter str in passbyval is different from the address of the local object str in main, but their values are the same.
In passbyref, printf("%s\t%p\n",*lit,&*lit); prints the string at lit and the address of *lit. Since lit is the address of the litstr in main, *lit is that litstr, so &*lit is the address of litstr. The value of litstr would be *lit.
Similarly, printf("%s\t%p\n",*str,&*str); prints the string at *str and the address of *str, which is the address of str in main.
What is the difference between passing a pointer by reference and passing a pointer by value in C?
There is no such thing as passing a pointer by reference in C, all variables are passed by value, even pointers.
My understanding is when you pass arguments to methods a new stack frame is created and those values are copied to different memory addresses unless passed by reference. If passed by reference the memory addresses are passed.
Again, the pointers are not passed by reference, a copy of the value stored in the pointer is passed, i.e. the address where it points to, you can test this by changing the value of the pointer inside the function, and check how that reflects on the original pointer, spoiler, it doesn't.
When working with pointers I noticed that if I pass a char by value and modify it in a different stack frame when I return back to the main stack frame the value of the ptr has been modified.*
What you are passing is an address, a memory location where some data is stored, when you change the data stored in that memory address it will be permanent, no matter where you do it, in fact that is one of the advantages of using pointers, for you to change the contents of some variable outside the scope where it's declared.
You need to understand how the pointers and arrays work.
pointer is a separate object having its own reference, holding the reference of the underlying object.
char *p = "aaa";
print("%p\n", (void *)p); //prints the reference of the string literal "aaa"
print("%p\n", (void *)&p); //prints the reference of the pointer `p`
Arrays are contignous chunks of memory. Arrays decay to pointers. Those pointers do not have physical representation in the memory and only are references to the first element of the array.
char p[] = "aaa";
print("%p\n", (void *)p); //reference of the first element
//of the array p the type is `char *`
//(pointer to char)
print("%p\n", (void *)&p); //reference of the first element of the
//array p the type is `char (*)[4]`
//(pointer to an array of 4 char elements)
What is the difference between passing a pointer by reference and passing a pointer by value in C.
In C, there are various ways arguments are pre-processed before being passed to a function.
No processing
A copy of the argument is given to the function. char *s = ...; puts(s);. puts() is given a copy of s.
Usual argument promotion
The argument is promoted to int, unsigned, double, ... before a copy is given to the function. float fl = 12.5f; printf("%g", fl); printf() is given a copy of double 12.5.
Function converted to an address
With tss_create(tss_t *key, tss_dtor_t dtor);, tss_dtor_t is a function pointer type void (*)(void*). tss_create(... , foo) does not take a function foo() and pass that. Instead a copy of the address of the function is passed.
Array converted to address of its first element
With char s[] = "Hello; puts(s);, A copy of &s[0] is passed to puts().
Now, are any of these like OP's pass by reference?
Yes.
With char *end[1]; strtod("123.4", end);, from the caller's point of view, end is adjusted in it entirety by strtod() and so acts and smells like "pass by reference" from the caller's POV. This is technically still "pass a copy", but the copy is the address of the argument's 1st element.
Other than that, I see no comparable "passing a pointer by reference and passing a pointer by value in C" in which to find a difference.

What is the address of a pointer in C?

int main()
{
int *p;
printf("%p \n", &p);
printf("%p \n", p);
return 0;
}
By executing this code I am receiving the following output:
0x16b77f710
0x104683f4c
I expected to get the same memory address, because the &p id not referenced to any other variable.
Why i am getting two different memory address?
Thanks,
The pointer is a normal object having (in your case type of int *). It cant point to itself because the type of such pointer would have to be int **
*image stolen from internet.
A pointer is a variable like any other. It has an address, which is typically the address in memory where that variable sits.
Like any other variable, a pointer variable also has some data in it. For a pointer variable, that data is the address of some other variable, the variable at which the pointer points.
The address of a variable, and the contents of a variable, are two totally different things. They are almost never equal.
Try this program, in which I give your variable p something to point to:
int main()
{
int i = 5;
int *p = &i;
printf("p: %p, p's address: %p\n", p, &p);
printf("i: %d, i's address: %p\n", i, &i);
}
You should notice two things:
As in your first program, "p" and "p's address" will be different.
Whatever value you see for "p", it will be the same as "i's address".
The reason is that a pointer, when declared, does not point to itself by default. Simplified you can imagine it in such a way that a pointer occupies 2 memory cells. 1 memory cell has the virtual address where the pointer itself is located (&p in your case), the 2nd memory cell contains the virtual address where the pointer points to (p in your case).
Since memory cells retain their value when they are deallocated, the cell containing the destination address of your pointer still contains an obsolete value from another, already completed process.
You would have the same phenomenon if you declare a new integer variable and then print its value with printf, you will see that there will already be some number in the new variable that will appear completely random. This is also due to the fact that there is still an obsolete value in the corresponding memory cell.
Let assume there is random memory block for just understanding name it a. Now assume that p is pointing to that memory block.
&p returns the address of memory block where p is present.
p returns the address of memory block(&a) to the variable/memory block(a) which p is pointing.
So of course it will give different memory addresses.
I expected to get the same memory address, because the &p id not referenced to any other variable.
Pointer variables do not automatically point to themselves; if you don't explicitly initialize them, then their initial value will be indeterminate (or NULL, depending on how they are declared).
There's nothing magic about pointer variables - like any other scalar, they store some kind of value; it's just that in their case, that value is an address of another object.
If you really want p to store its own address, you'll have to do something like
p = (int *) &p;
The cast is necessary because the type of the expression &p is int **, and you can't assign a pointer value of one type to a variable of a different pointer type. But, pointers to different types are not guaranteed to have the same size, representation, or alignment. On modern commodity hardware like x86 you can probably count on int * and int ** having the same size and representation, just be aware that doesn't have to be the case everywhere.

C - Get pointer adress to string

I'm trying to re-code the printf function. I'm stuck on the %p flag.
As you know, %p flag prints the address of a pointer. The problem is that I would like to get this address in a character string (char *), in order to print it.
Is there a way to get an address ?
Thank you.
You are probably lost on what is a pointer.
Consider this code: char *foo = "bar";
Here, foo is a pointer. A pointer is just a variable that holds the address of some space in memory. Here foo IS the pointer to the string "bar".
Also, address in memory are not magic, they are themselves a number. So you just need to print the number stored in your variable.
Unrelated, it's not a smart move to post a question about a school project, in your real name, with context. It could allow other students or worse, your administration to find that you did not do your personal projects by yourself.

how to send integer number via sheared memory in linux

I am trying to send integer data via a shared memory in linux it works very well with string
const char *msg="hello";
but when I try this gives me error
const int *msg=25;
and when I try to print the contain of the address for string works
printf("%s",(char *) ptr);
but for this I have error
printf("%d",(int *)ptr);
and I try to write this but I give me the address not the contain of the address
printf("%d",*(int *)ptr);
In your code,
const int *msg=25;
is likely to produce weird result, as, you're assigning a pointer address to get a value 25 which is most likely to be an invalid address in respect to your program. It's most likely you don't intend to do that.
Instead, write
const int msg=25;
and use &msg to get the address of that variable.
FWIW, the above changes (note the plural form) will solve the issue with printf(), too, and, the casts are not required, anyway.
printf("%s",(char *) ptr);
The cast to char * is unneeded.
printf("%d",(int *)ptr);
In order to get the value the pointer is pointing to, use *. So you'd write:
printf("%d", *ptr);
Also dont assign raw addresses to pointers, because you (usually) dont know what is in that address. In your example, address 25 might be anything. Dereferencing that pointer will likely cause a segfault( https://en.wikipedia.org/wiki/Segmentation_fault)
So instead of that you should do this:
int a = 25;
int *addr = &a; /* addr contains the address of a */
To print addr:
printf("%p", addr);
Or if %p is unavailable for your compiler, use %u.

Memory allocation for constant char array

If I write char * p = "Welcome".
I can see the address for p. But what's the address for the string i.e at which address Welcome stored?
If I write again char *s = "Welcome". p and s will point to same address?
In a debugger, if you inspect p, you will see the address of the string.
&p is the address of p itself.
And no, p and s are not guaranteed to point to the same address, but they might.
"Welcome" is string constant and it is stored in read only data section of memory but pointer p is created in stack which points to this string literal
String constant "Welcome" often are putted in "read-only-data" section of memory.
Here are good explanations about: String litereals where do they go and data segment
you can find the address of string constant "Welcome" by
printf("%p",p);
If I write again char *s = "Welcome". p and s will point to same
address?
Maybe same string constant are putted in the same address, maybe not.

Resources