This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why do I get a segmentation fault when writing to a string?
I was writing a simple string function. The problem is: I declare a char pointer, then once I try to update a specific character, the program crashes.
I have checked some previously written string processing, I found that they modify specific characters. But when I try to run them, I get the same problem.
Sample:
stringprocess()
{
char *s;
s=" I am c programmer";
s=" but, ..... um";
*s='x'; //program crashes here...
*p="abc";
*s=*p; // this also cause crashing
........
}
Why does this happen?
s=" but, ..... um";
s points to a string literal. Trying to modify a string literal invokes undefined behaviour. Often, string literals are stored in read-only memory, then a crash is the immediate consequence of such an attempt.
You should use a char s[100] (just for example) or a malloced pointer if you want to modify the contents.
Related
This question already has answers here:
How dangerous is it to access an array out of bounds?
(12 answers)
Array index out of bound behavior
(10 answers)
No out of bounds error
(7 answers)
Closed 1 year ago.
int main ()
{
char *strA = "abc";
int tam_strA = strlen(strA);
char strB[tam_strA];
strB[0] = 'a';
strB[1] = 'b';
strB[2] = 'c';
strB[3] = 'd';
strB[9] = 'z';
printf("%c", strB[9]);
return 0;
}
It prints 'z' normally. Why it doesn't return segmentation fault error? Since I'm trying to access an index that shouldn't exist because the size (amount of indexes) of strB is equal to tam_strA which is equal to 3.
Also, is there any difference/problem on doing char strB[strlen(strA)]; instead?
C language does not have a specification that stops you from accessing invalid memory, nor does it guarantee a segmentation fault. The only promise which is made is that, if you attempt to access invalid memory, that will cause undefined behavior.
Segmentation fault is one of the possible outcomes, NOT the ONLY one.
That said, the only problem with
char strB[strlen(strA)];
is that, strB will not be long enough to hold the content in strA, because it will lack one byte to hold the null-terminator. Sure, byte-wise use will be fine, but if you want to copy the content (or any content of the same length as strA) and use strB as a string, you'll run past the allocated memory (in absence of the null terminator), invoking undefined behavior.
You only get Segmentation fault when accessing the memory that you do not own. You own your entire stack. strB[9] is a valid memory access in the eyes of the OS. The reason that you shouldn't do this is because the compiler doesn't know that you're using that memory, so it might decide to use that memory for other uses. It's also good for improving readability and minimising mistakes from the programmer. And, the standard defines the using of undeclared memory to be undefined behaviour, so you can't use it safely. Declaring a variable like int x;(or an array) tells the compiler that you will use the memory at x.
This is actually related to this question: Why does the first element outside of a defined array default to zero?. Read the much more detailed answers over there.
This question already has answers here:
Why doesn't my program crash when I write past the end of an array?
(9 answers)
Closed 3 years ago.
I have the following code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char buffer[2];
strcpy(buffer, "12345678910");
printf("%s\n", buffer);
return 0;
}
Since, I have already defined the char array with size 2, I shouldn't be able to put in more than 2 char plus null terminating character. Yet, it is able to take more than that without any buffer overflows or segmentation faults. Even if I copy the string strcpy(buffer, "123456789101298362936129736129369182");, it works fine. The error is generated when I push strcpy(buffer, "1234567891012983629361297361293691823691823869182632918263918");.
More of a theroetical question than a practical, but I hope it helps the new and the experienced programmers alike since it talks about the fundamentals, and helps improving coding ethics. Thanks in advance.
The simple answer is that C does not protect you from yourself. It's YOUR responsibility to check boundaries. The program will happily read and write wherever you instruct it to. However, the operating system may say something if you do this, which is usually a "segmentation fault". A worse scenario is that it may overwrite other variables.
This is a source of many bugs in C, so be careful. Whenever you're writing outside outside a buffer, you're invoking undefined behavior and these can manifest themselves in various ways, including the program working as it should, overwriting variables and segmentation faults.
I shouldn't be able to put in more than 2 char plus null terminating character
This is a common bug. It's NOT "plus null terminating character". It's INCLUDING null terminating character.
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
This question already has answers here:
Assigning strings to arrays of characters
(10 answers)
Closed 9 years ago.
int main()
{
char s[]="stack";
s="overflow";
}
This is not allowed.Its gives an error.But below code works fine.
int main()
{
char s[]="stack";
strcpy(s,"overflow");
}
Why this happens?
The variable s represents a pointer to the string. More specifically, it refers to the memory address of the first letter in your string "stack". Due to this reason, the operation s="overflow" makes no sense. How can you set the value of s (a pointer) to a string?
Keep in mind that C is a very low-level language, so you have to be wary of things that might seem intuitive to you not behaving the way you expect them to.
This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 9 years ago.
This is my program and it is seg faulting when i try to do s[0] = s[1].
I don't understand why this wouldn't work as all i am doing is taking value in s[1] and putting it in s[0].
#include<stdio.h>
void main() {
char x;
char *s="stackoverflow";
s[0] = s[1]; // it is segfaulting here
x = s[0]; //this works though
printf("this is: %s\n",s);
}
i am compiling using gcc filename.c and running it using ./a.out in ubuntu terminal.
Thank you.
When you do: char *s="stackoverflow"; then s is a pointer that points to a memory that is in the code part, so you can't change it. Because it's read-only, you're getting segmentation fault at runtime (if you used the const keyword, you would get a compilation error, which is better.. So it's recommended to use const if you don't want to make changes on strings).
If you do char s[]="stackoverflow"; then s is an array of chars that are on the stack, so you can change it.
You should not attempt to change a string literal. If you want to modify the value, make a copy using strcpy for instance.
Change declaration of variable:
char s[] = "stackoverflow";
will remove the problem you have, as variable will have storage allocated on entering the scope and initialized with the data given.