This question already has answers here:
Where does the compound/string literals get stored in the memory?
(4 answers)
Closed 9 years ago.
I have a following program:
#include<stdio.h>
char * test()
{
char * rt="hello";
return rt;
}
void main()
{
printf("\n %s \n", test());
}
here, it correctly prints hello while if rt is not a constant pointer like char rt[]="hello" it prints garbage. My understanding, in latter stack gets freed when function returns from test but what happens with above case? where does the memory for char *rt is allocated?
Extending above part, If I try to do char rt[]="hello" and if i try rt="hrer" it throws error while with char *rt="hello" it works fine but we can not change particular character in a string with later case. Please help me to understand it. Thanks.
Your string "hello" is what is called a string literal. It resides in what is called the data segment of your program, which is a region of memory. Any other string literals throughout your code are put there as well. This region is loaded once, and never destroyed.
So, your pointer rt is pointing somewhere into that region.
But, if you declare char rt[] = "hello", you are declaring an array named rt[] on the stack and the array is 6 bytes long (hello + null terminator). When the function returns, the stack is freed, so, this memory will be invalid.
Some more information on string literals are here: C String literals: Where do they go?
The string Hello gets set into the read portion of the executable part of the program. The function returns a pointer to that.
The use of an array (in the second case) means that it gets copied onto the stack.
End of the function it gets zapped - hence garbage
Related
This question already has answers here:
Function returning address of local variable error in C
(3 answers)
Closed 3 years ago.
I have two cases to return the string. One returns a pointer and other returns the char array. The first case works fine while printing the string, but I am getting a segmentation fault error on the second case. I want to know why this is happening?
This is the first case, and it gives the output.
char* voice(void){
return "hey!";
}
int main(){
printf ("%s\n", voice()); //output: hey!
return 0;
}
This is the second case, and it gives a segmentation fault.
char* voice(void){
char str[] = "hey!";
return str;
}
int main(){
printf ("%s\n", voice()); //segmentation fault
return 0;
}
Second case does not work because you are returning address of a local array.
The scope of local array "str" is limited to the function. So the array is valid only within that function. It becomes invalid once you go out of the function. The behavior of the program will be undefined in this case.
In 1st case, you are returning address of a string constant. String constants are allocated in a separate memory space and they will be retained throughout the program. So the address of string will be still valid even after you return from voice().
In C, local arrays (like str in your second example) are by default stored in the stack section of memory. That means that the section of memory that stores str becomes unreachable as soon as voice() returns, thus producing the segmentation error when you are trying to reach unreachable memory.
String literals (like "hey") are stored in the code section of memory. Even when voice() returns, the string is still stored in the code section of memory.
This question already has answers here:
How can I correctly assign a new string value?
(4 answers)
Closed 4 years ago.
Why does this not return a segmentation fault 11?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
char *test;
test = (char*) (malloc(sizeof(char)*3));
test = "foo";
printf("%s\n", test);
test = "foobar";
printf("%s\n", test);
return 0;
}
My outcome is
foo
foobar
I'm fairly new to C, but when I was compiling this using both gcc on mac and Windows Debugger on Windows 10, it doesn't crash like I expected.
My understanding is that by using (char*) (malloc(sizeof(char)*3)), I am creating a character array of length 3. Then, when I assign test to the string foobar I am writing to 6 array positions.
I'm left sitting here, staring at my apparently valid, runnable code scratching my head.
test = "foo";
Here you do not copy the string to the allocated memory, test no longer points to the allocated memory, instead it points to the string literal "foo". Same goes for "foobar". Also as pointed out in the comments the address of the allocated memory is lost and therefore it is a memory leak (since there is no way to retrieve the address of the memory).
If you want to copy a string to another destination you need to use strcpy or loop over every character.
If you write or read outside bounds of the allocated space you are invoking undefined behavior. That means that basicly everything can happen, also that it works.
Your program never writes to the location pointed to by the return from malloc(). All you've done with e.g. test = "foo"; is change what test points to, which by the way is a memory leak since you've then lost what malloc() returned.
To properly use the memory you allocated with malloc(), use strcpy(), snprintf(), etc.
Also, don't forget the null terminator in your C strings. To properly store e.g. "foobar" you need at least 7 bytes, not 6.
First thing is that you waste the memory allocated by malloc unnecessorily by storing the address of foo into that.
If you are going to point to string in code section then there is no need to allocate memory to the pointer.
When to allocate memory to pointer
e.g. when you intended to scan 'n' number of bytes from keyboard in pointer.
char *ptr,num_char;
scanf("%d",&num_char);
ptr = (char *)malloc(num_char*sizeof(char));
scanf("%s",ptr);
This question already has answers here:
Returning an array using C
(8 answers)
Closed 8 years ago.
I have an idea on dangling pointer. I know that the following program will produce a dangling pointer.But I couldnt understand the output of the program
char *getString()
{
char str[] = "Stack Overflow ";
return str;
}
int main()
{
char *s=getString();
printf("%c\n",s[1]);
printf("%s",s); // Statement -1
printf("%s\n",s); // Statement -2
return 0;
}
The output of the following program is
t
if only Statement-1 is there then output is some grabage values
if only Statement-2 is there then output is new line
Your code shows undefined behaviour, as you're returning the address of a local variable.
There is no existence of str once the getString() function has finished execution and returned.
As for the question,
if only Statement-1 is there then output is some grabage values if only Statement-2 is there then output is new line
No explanations. Once your program exhibits undefined behaviour, the output cannot be predicted, that's all. [who knows, it might print your cell phone number, too, or a daemon may fly out of my nose]
For simple logical part, adding a \n in printf() will cause the output buffer to be flushed to the output immediately. [Hint: stdout is line buffered.]
Solution:
You can do your job either of the two ways stated below
Take a pointer, allocate memory dynamically inside getString() and return the pointer. (I'd recommend this). Also, free() it later in main() once you're done.
make the char str[] static so that the scope is not limited to the lifetime of the function. (not so good, but still will do the job)
your str in getString is a local variable, which is allocate on stack, and when the function returns, it doesn't exist anymore.
I suggest you rewrite getString() like this
char *getString()
{
char str[] = "Stack Overflow ";
char *tmp = (char*)malloc(sizeof(char)*strlen(str));
memcpy(tmp, str, strlen(str));
return tmp;
}
and you need to add
free(s);
before return 0;
In my case, pointer tmp points to a block memory on heap, which will exist till your program ends
you need to know more about stack and heap
Besides, there is still another way, use static variable instead
char *getString()
{
static char str[] = "Stack Overflow ";
return str;
}
PS: You get the correct answer for the following statement printf("%c\n",s[1]); is just a coincidence. Opera System didn't have time to do some clean work when you return from function. But it will
Array is returned as a pointer yet the array itself is the garbage after return from function. Just use static modifier.
What's concerning s[1] is OK. The point is, it's the first printf after getting the dangling pointer. So, the stack at this point is still (probably) intact. You should recall that stack is used for function calls and local variables only (in DOS it could be used by system interrupts, but now it's not the case). So, before the first printf (when s[1] is calc'ed), s[] is OK, but after - it's not (printf' code had messed it up). I hope, now it's clear.
This question already has answers here:
Difference between char* and char[]
(8 answers)
String Literals
(3 answers)
Closed 9 years ago.
#include <stdio.h>
#include <string.h>
int main(void){
char s1[30]="abcdefghijklmnopqrstuvwxyz";
printf("%s\n",s1);
printf("%s",memset(s1,'b',7));
getch();
return 0;
}
Above code works but when I create s1 array like this,
char *s1="abcdefghijklmnopqrstuvwxyz";
it does not give any errors in compile time but fails to run in runtime.
I am using Visual Studio 2012.
Do you know why?
I found prototype of memset is:
void *memset( void *s, int c, size_t n );
char s1[30] allocates a writable memory segment to store the contents of the array, char *s1="Sisi is an enemy of Egypt."; doesn't - the latter only sets a pointer to the address of a string constant, which the compiler will typically place in a read-only section of the object code.
String literals gets space in "read-only-data" section which gets mapped into the process space as read-only (So you can't change it).
char s1[30]="abcdefghijklmnopqrstuvwxyz";
This declares s1 as array of type char, and initialized it.
char *s1="abcdefghijklmnopqrstuvwxyz";
Will place "abcdefghijklmnopqrstuvwxyz" in the read-only parts of the memory and making a pointer to that.
However modifying s1 through memset yields an undefined behavior.
An very good question!.
If you make gcc output the assembly, and compare the output, you could find out the answer, and the following is why:
char s1[30]="abcdef";
when defined in a function, it will define an array of char, and s1 is the name of the array. The program will allocate memory in stack.
when define globally, it will define a object in the program, and the object is not an read only data.
char* s2 = "abcdef"; only define a point of char, which point to an const char stored in the .rodata, that is the read only data in the program.
To make program run efficiently and make the progress management easily, the compiler will generate different sections for a given code. Constant chars, like the char* s2 = "abcdef"; and the printf format string will be stored in the .section rodata section. After loading into the main memory by the loader of the OS, this section will be marked as read only. That is why when you use memset to modify the memory which s2 point to, it will complain Segment fault.
Here is an explaination: Difference between char* and char[]
I'm trying to understand where things are stored in memory (stack/heap, are there others?) when running a c program. Compiling this gives warning: function return adress of local variable:
char *giveString (void)
{
char string[] = "Test";
return string;
}
int main (void)
{
char *string = giveString ();
printf ("%s\n", string);
}
Running gives various results, it just prints jibberish. I gather from this that the char array called string in giveString() is stored in the stack frame of the giveString() function while it is running. But if I change the type of string in giveString() from char array to char pointer:
char *string = "Test";
I get no warnings, and the program prints out "Test". So does this mean that the character string "Test" is now located on the heap? It certainly doesn't seem to be in the stack frame of giveString() anymore. What exactly is going on in each of these two cases? And if this character string is located on the heap, so all parts of the program can access it through a pointer, will it never be deallocated before the program terminates? Or would the memory space be freed up if there was no pointers pointing to it, like if I hadn't returned the pointer to main? (But that is only possible with a garbage collector like in Java, right?) Is this a special case of heap allocation that is only applicable to pointers to constant character strings (hardcoded strings)?
You seem to be confused about what the following statements do.
char string[] = "Test";
This code means: create an array in the local stack frame of sufficient size and copy the contents of constant string "Test" into it.
char *string = "Test";
This code means: set the pointer to point to constant string "Test".
In both cases, "Test" is in the const or cstring segment of your binary, where non-modifiable data exists. It is neither in the heap nor stack. In the former case, you're making a copy of "Test" that you can modify, but that copy disappears once your function returns. In the latter case, you are merely pointing to it, so you can use it once your function returns, but you can never modify it.
You can think of the actual string "Test" as being global and always there in memory, but the concept of allocation and deallocation is not generally applicable to const data.
No. The string "Test" is still on the stack, it's just in the data portion of the stack which basically gets set up before the program runs. It's there, but you can think of it kind of like "global" data.
The following may clear it up a tad for you:
char string[] = "Test"; // declare a local array, and copy "Test" into it
char* string = "Test"; // declare a local pointer and point it at the "Test"
// string in the data section of the stack
It's because in the second case you are creating a constant string :
char *string = "Test";
The value pointed by string is a constant and can never change, so it's allocated at compile time like a static variable(but it's still stack not heap).