Memory allocation for constant char array - c

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.

Related

Why is a pointer to a string stored in .rodata but a pointer to the int is on the stack?

I have the following questions related to the C language:
Why is char *p="Harish" stored in .rodata segment?
Why is int *p=90 stored on the stack?
When you do this:
char *p = "Harish";
you're doing the following:
You're creating a pointer on the stack, named p.
Initializing it to the address of the literal string "Harish". This string has to be stored somewhere that won't go away when the function exits, so it's stored in the read-only data segment (it's a constant string, so it doesn't need to be writable).
By contrast, when you do this:
int *p = 90;
you're just creating a pointer, but not anything for it to point to. You're just setting the pointer to point to the address 90. As in the above case, the pointer is in the stack. Nothing goes into the .rodata segment because the declaration doesn't create anything for it to point to.
char *p="Harish"
In the above line “Harish” is stored in a shared read only location. but pointer p is stored in a read-write memory. You can change p to point something else but cannot change value at present p. So this kind of string should only be used when we don’t want to modify string at a later stage in program.

I need a greater understanding of what a pointer actually points to

What is the actual value of pointer:
char *ptr;
And it's pointing to a memory address, correct?
Not yet; it's uninitialized.
What you're asking is like asking what number int i; refers to.
I will try to explain in a simple way, (sorry if my English is not god enough i am learning)
Let say you have an array of characters:
char a[5];
Then you want to create a pointer to the address of the first element:
char *p = &a[0];
Now since the name of an array is a synonym for the location of the
initial element you can rewrite to the following statement:
char *p = a;
Now here is where magic takes place, as the previous character pointer points to the address of the first element you can do stuffs like the following:
instead of getting the 'i'-th element from a[i], you can move the pointer 'i' places to reference the address of the value contained in the 'i'-th position and then get it's value:
char value = *(a + i);
Font(The C programming language 2nd Edition, Chapter 5)
char *ptr;
It is not pointing any memory address until it is initialized;
But you can use it to point an address.
Suppose,
int i=0;
i has an address in memory. if it become 0xFFFF0 then when you write
ptr=&i;
then your pointer points to address 0xFFFF0 .
now suppose,
int array[5]={0}; is an array.
then if you write-
ptr=array;
then ptr points to the starting address of array because array name is an address.
Yes, it is pointing to the address of the variable.
The variable might be on the stack if the variable is declared inside a function, or at the top of RAM if declared at the top level.
As the other answers point out, you haven't made it point to anything yet, so dereferencing the pointer will likely result in a segmentation fault.
You need to do something like
char ch;
char *ptr = &ch;

How memory allocation works for char* without explicitly allocating

In the following (legal) c code, there is no memory explicitly allotted to the pointer p.
AFAIK, i cannot get an int *p to point to a value 5 without explicitly allocating memory.
int main()
{
char *p;
p = "Hello";
return 0;
}
How's char* pointers different
Where's the memory allocated for "Hello"
When you put literal strings such as "Hello" in your program, the compiler creates an array of characters in the data area of the program (called the Data Segment).
When you assign:
p="Hello";
the compiler takes the address of the string literal in the data segment and puts it in the pointer variable p.
Notice that string literals are different to numeric literals. The type of a string literal is const char[] - which you can assign to a char* pointer. An integer literal is just type int.
Also note that a numeric literal does not need to be stored in the data segment - in most cases such literals are placed directly in the machine code instructions. Thus there is no address which you could point p towards.
If you tried to do this (as per your comment):
int *p;
*p = 5;
what you are actually saying is that you want to store the number 5 into the location pointed to by p (which would be undefined in this case, since we never set p to anything). You would probably get a segfault.
If you tried to do this:
int *p;
p = 5;
what you would be telling the compiler to do is to convert the value 5 into a pointer to an integer and store that in p, with the result that the pointer p now points at address 5. And you would probably get a warning like this:
t.c:7: warning: assignment makes pointer from integer without a cast
In other words, you are trying to convert an integer to a pointer - probably not what you thought you were trying to do.
In C, string literal like "Hello" will be exaluated to a char * type value, i.e. its base address, you could use it to initialize a pointer to char.
In the runtime, string literals usually is located in some read-only memory segmentation.
By the way, it looks like you confused pointer variable and the address pointed to by a pointer variable.
By statements like char *p;, you defined a pointer variable, compiler will allocate the necessary memory to store this variable. But in this time, this pointer has not been initialized, so it does not have a determined value, which means it could point to anywhere.
By statements like p = "Hello";, you assigned pointer p a value, now it points to some determined memory address, this memory segmentation could be allocated by compiler, or be allocated by yourself, for example p = malloc(...);.
p is pointing to string literal Hello where memory is allocated from read only data section. And the moment when you modify it you get a Undefined Behavior and may result in to segmentation fault.
C standard says,
String literals - An ordinary string literal has type “array of n const char” and static storage duration (3.7)
The jobs was done for you by the compileer. It allocates space in the data segment and stores the string "Hello" and assigns the base address of this array to the pointer that is p1 in your case.
However this array "Hello" will be a const array. You will not be able to modify the data once it created.
If you try to modify the data then you will get unexpected results.

Get address of a string-constant in 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.

Memory allocated in char * var; declaration

In C, declaring a char pointer like this
char* p="Hello";
allocates some memory for a string literal Hello\0. When I do this afterwards
p="FTW";
what happens to the memory allocated to Hello\0? Is the address p points to changed?
There is no dynamic memory allocation in either statement.
Those strings are stored in your executable, loaded in a (likely read-only) section of memory that will live as long as your process does.
The second assignment only changes what p points to. Nothing else happens.
The memory remains occupied by "Hello". It is lost (unless you have other references to it).
The address p is pointing to (the value of p) is changed of course.
In this case, "Hello" is created at compile time and is part of the binary. In most situation "Hello" is stored in read only memory. "FTW" is also part of the binary. Second assignment will only change the pointer.
in addition - "Hello" and "FTW" have static storge duration as Met have pointed out
It creates a string constant that cannot be modified and should be used as it is.
If you try doing
p[0]='m';
It would give segmentation fault since this is not string literal with allocated memory in which you can reassign and read back values.
what if
p = getbuffer();
getbuffer()
{
return buf = malloc(buf, size);
}
how can free this memory before allocating new memory to p! imagine that p should use getbuffer() many times.

Resources