strtok() - Segmentation Fault [duplicate] - c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
strtok giving Segmentation Fault
I try to use strtok function to split string in many tokens but in this example it returns me a seg. fault error. Where i'm in wrong??
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv){
int i=0;
char * string = "HI:HOW:ARE:YOU:?", *tmp;
while(1){
if(i==0) tmp=strtok(string,":");
else tmp=strtok(NULL,":");
if(tmp==NULL) break;
printf("%s\n",tmp);
i++;
}
return 1;
}

Change
char * string = "HI:HOW:ARE:YOU:?"
for
char string [] = "HI:HOW:ARE:YOU:?"
With char string [] you have an array, and char * you have a pointer. When you declare an array, it will request space to allocate the size of your string. The char * string creates a pointer that points to a literal string.
The problem with char *string it is that the point should not be changed because string literals are typically stored in read-only memory, thus causing undefined behavior 33
( for more detail read this https://www.securecoding.cert.org/confluence/display/seccode/STR30-C.+Do+not+attempt+to+modify+string+literals )
Therefore, since with strtok the contents of the string is modified and broken into smaller strings (tokens) you got problems.

Related

Cannot use strcpy with 2 string (segmentation fault) [duplicate]

This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed last year.
What's wrong with this code?:
int main(int argc, char ** argv) {
char strs[] = "What will be printed?";
char *str1;
char *str2;
strs[5] = '\0';
str1 = strs;
strcpy(str2, str1);
printf("%s\n", str2);
return 1;
}
I want it to print "What", instead i get segmentation fault.
I believe it has something to do with the strcpy(str2, str1);, but what is the explanation for that? The signature of strcpy is char* strcpy(char* destination, const char* source); and that's exactly what i did.
Could you explain that to me?
Your destination string is not initialized - it has no memory reserved for itself. An attempt to write to it causes invalid memory access (you're trying to overwrite something completely random and unplanned) and is followed by a segmentation fault.
One clean way to initialize a string is to define a global macro variable that just sets the largest size of strings you plan on using in your code,
#define MAXBUF 100
Then in your main you can simply write:
char str2[MAXBUF];
And your program will work. Alternative is to use dynamic memory allocation which you will likely learn about soon.
#include <stdio.h>
#include <string.h>
int main() {
char *src = "What will be printed?";
char dest[100];
int START = 0; // start of copy
int LENGTH = 5; // length of copy
// copies up to LENGTH characters from the string pointed to, by src to dest. In a case where the length of src is less than that of LENGTH, the remainder of dest will be padded with null bytes.
strncpy(dest, &src[START], LENGTH);
printf("%s\n", dest);
return 0;
}

why does passing C string into function as char* cause runtime error (but passing C string defined as char[] is ok)? [duplicate]

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 2 years ago.
I have a simple C program as follows:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void convertToUpperCase(char* sPtr);
int main(int argc, char** argv) {
char myString[] = "cHaRacTerS aND $32.95";
char* anotherString = "cHaRacTerS aND $32.95";
convertToUpperCase(myString); // THIS IS OK!
convertToUpperCase(anotherString); // THIS CAUSES RUNTIME ERROR
// (ie. build success but run fail)!
return (EXIT_SUCCESS);
}
void convertToUpperCase(char* sPtr) {
while (*sPtr != '\0') { // current character is not null (ie. end of string).
*sPtr = toupper(*sPtr); // turns valid characters into upper case
++sPtr; // point to next character within the string.
}
}
It seems like passing anotherString into the function that expects a char* is the problem. From my understanding, both myString and anotherString are char* in C.
It seems to me the problem is how they are defined. For myString I defined it as an array of characters with a null terminator at the end. For anotherString it is a character pointer to a string literal somewhere.
But I can't figure out why the way they are defined matters in this situation.
Thanks in advance :)
edit: used specific terms as suggested by answers.
Because when you declare a literal, it is read only.
char myString[] = "cHaRacTerS aND $32.95"; // readwrite memory
char* anotherString = "cHaRacTerS aND $32.95"; // placed in readonly memory
Edit: to clarify, it is not only read-only, it is UB to write to a string literal. Thanks for that comment, #chux-reinstate-monica

Segmentation fault when reversing string in C [duplicate]

This question already has answers here:
Reverse a string in C solution segfaulting
(2 answers)
Closed 10 years ago.
I have the following code which its main purpose is reverse the characters of a string. So, for example, the string I love cats would be converted to stac evol I.
#include <string.h>
#include <stddef.h>
#include <stdio.h>
void reverseString(char *str)
{
int size = strlen(str);
char *end = str + size - 1;
char tmp;
while (end > str) {
tmp = *str;
*str = *end;
*end = tmp;
end--;
str++;
}
}
int main()
{
char *str = "Y U SEGMENTATION FAULT?";
reverseString(str);
}
When I run this, I get a segmentation fault, and I fail to see why. Also, another question I have is the time complexity (Big O) of this function. I believe it should be O(n/2), since I am not going through all the array but just the half of it. Am I right?
You are trying to modify a character literal, a string in read only data segment. Make a copy/duplicate of it on the heap with strdup, for example:
char *str = strdup("It's OK now");
Or make it a local array (place the string on the stack):
char[] str = "It's OK now";

Segmentation fault while using char * string but not with char string[11] [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why do I get a segmentation fault when writing to a string?
Why do I get a segmentation fault when I try to modify a string constant?
I was trying to run the following two codes and I am getting a segmentation fault with file2.c but with file1.c I am not getting any fault. Can somebody explain what is the difference between the following codes :
file1.c
#include <stdio.h>
int main()
{
int i;
char string[11] = {"HelloThere"};
string[10] = '\0';
for(i =0;i<5;i++)
{
string[i] = 'a';
}
printf("%s\n",string);
}
and :
file2.c
#include <stdio.h>
int main()
{
int i;
char * string;
string = "HelloThere";
for(i =0;i<5;i++)
{
string[i] = 'a';
}
printf("%s",string);
}
This is because the assignment
char string[11] = {"HelloThere"};
copies the string constant into a writable memory, while
char * string = "HelloThere";
leaves it in the read-only memory. While it is absolutely OK to write to the writable memory (duh!) writing to read-only memory is undefined behavior, and may trigger a crash.
Note that you do not need to specify the size of your string explicitly, unless you want to allocate more memory than is required for your string literal:
char string[] = {"HelloThere"}; // <<== The size is empty
string = "HelloThere";
then
string[i] = 'a';
is wrong - you're trying to modify a string literal, which you can't. This results in undefined behavior, so anything can happen, including crashes.
However,
char sring[11] = "HelloThere";
creates an auto array (copying the contents of the string in it beforehands) and that's writable, it's allowed to modify their elements.

Segmentation fault (core dumped) in strtok [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Memory Allocation char* and char[]
Why does the following program give a Segmentation fault in run-time ?
#include <stdio.h>
#include <string.h>
#include <malloc.h>
main()
{
char * str = "Have a. nice, day :)";
char * ptr;
ptr = strtok( str, " .,");
printf("%s",ptr);
}
But if I use char str[] = "Have a. nice, day :)"; it gives me the output. Why is that i get the error even though strtok definition is char* strcpy( char * , const char * ) ???~
strtok modifies the argument, str points to a string literal, modifying a string literal causes undefined behavior. Initializing a non-const char* with a string literal is in fact deprecated.
When you write str[], str becomes a mutable array initialized with the string.
strtok modifies the string passed to it. I suspect it has something to do with char * = "literal string" giving you a pointer to the string in the .data section, while char[] = "literal string" allocates a buffer on the stack, and copies the initial contents from the .data section.

Resources