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 6 years ago.
In C language I am trying to assign a value to pointer string. I cannot use char array, I have to use pointer string. So please tell how can I do that?
I am doing something like this (code given), but when I run my code an error is prompted program stopped working.
#include <stdio.h>
int main (void) {
char *myString = " ";
int value = 1;
myString[0] = value+'0';
printf("%s\n",myString);
return 0;
}
You cannot modify a string literal: myString is initialized to point to constant storage for the string literal. Attempting to modify it invokes undefined behavior. Use strdup() to create a copy of the string:
#include <stdio.h>
#include <string.h>
int main(void) {
char *myString = strdup(" ");
int value = 1;
myString[0] = value + '0';
printf("%s\n", myString);
free(myString);
return 0;
}
strdup() is a function standardized in POSIX, that allocates a block of memory from the heap long enough to receive a copy of its string argument. It copies the string into it and returns a pointer to the block. Such a block can be modified, and should be freed with free() when no longer needed.
Related
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 last month.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
char *str;
int len;
printf("Enter the expression: \n");
scanf("%[^\n]", &str);
printf("%s\n", str);
len = strlen(str);
printf("%d\n", len);
}
I am trying input a string into a string pointer but it keeps giving me a segmentation error, however when i initialize it as char array it works fine.
It looks like you are trying to get scanf to allocate the necessary memory for the string. That option is only available as an extension in some implementations, but here's how that would work:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) { // note the proper declaration
char *str = NULL;
int len;
printf("Enter the expression: \n");
if(scanf("%m[^\n]", &str) == 1) { // add `m` to malloc memory for the string
printf("%s\n", str);
len = strlen(str);
printf("%d\n", len);
free(str); // and `free` it after use
}
}
This is because you are using the scanf function to write to an uninitialized pointer str. The & is also uneeded for passing a pointer for scanf. A better way to handle the input would be to use fgets() or getline() and allocating memory dynamically using malloc() to store the input string.
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
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.
I am writing a code for squeeze(s1,s2) that deletes each character in string s1 that matches any character in string s2 and I get "Segmentation fault (core dumped)" when I try to run the program.
I believe the error comes from in how i call the function inside the main(). I am a beginner and I don't know how to call functions. Please help!
#include<stdio.h>
void squeezer(char s[], char c[]);
main()
{
squeezer("abcdefgabcdefgabcdefg", "abcd");
}
void squeezer(char s[], char c[])
{
int i,j,k,z;
for(k=0; c[k] != '\0'; k++) {
for(i=j=0;s[i] != '\0';i++) {
if (s[i] != c[k]) {
s[j++] = s[i];
}
s[j] = '\0';
}
}
for(z=0; z < j; z++)
printf("%c",s[z]);
}
You are passing string literal to your function and then trying to modify it. You can't modify a string literal. Modifying a string literal invokes undefined behavior. In such case you may get either expected or unexpected result You may get segmentation fault or program crash too.
You can change your main function as
int main(void)
{
char s1[] = "abcdefgabcdefgabcdefg";
char s2[] = "abcd";
squeezer(s1, s2);
}
Must read: comp.lang.c FAQ list ยท Question 1.32.
String literals are "constant", read-only. You cannot change them, and that is what squeezer() tries to do.
You're writing to string literals, which is undefined behaviour. If your compiler put them in read-only memory, then your program should segfault. Try making writable copies of your strings in main, like so:
int main(int argc, char** argv)
{
char s[] = "abcdefgabcdefgabcdefg";
char c[] = "abcd";
squeezer(s, c);
return 0;
}
Depending on the C compiler and operating system you are using, the string literal you pass to squeezer may be "read-only" -- i.e. immutable -- at run-time. This is the same mechanism meant to prevent modification of compiled code at run-time.
The fix is to allocte a character array large enough to hold s using malloc or declare a char s[80] in main or as a global variable and then use strcpy to copy your first string literal into s before passing it as the first argument to squeezer.
Alternatively, you could pass the allocated or declared array variable as a third argument to squeezer and copy the "squeezed" string into it. Or, if you want to make squeezer as robust as you can, allocate a result array with malloc in squeezer that is strlen(s) in size, use it to accumulate the "squeezed" letters, and then return the pointer to the allocted array from squeezer whose return type will have changed from void to char *.
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.
#include <stdio.h>
#include <conio.h>
void test(char *p)
{
p = p + 1;
*p = 'a';
}
int main()
{
char *str = "Hello";
test(str);
printf("%s", str);
getch();
return 0;
}
When I run this code it gives segmentation error ? why is this happening. The const theory is not clear to me... whereas if I declare str as char str[], it does the job. Are they not both basically the same things ?
str is pointing to a string literal, you are attempting to modify the string literal in the function test on this line:
*p = 'a';
It is undefined behavior to attempt to modify a string literal. You can alternatively, make a copy of the string literal into a array as follows:
char str[] = "Hello";
now it is perfectly ok to modify str. From the draft C99 standard, under section 6.4.5 String literals paragraph 6:
It is unspecified whether these arrays are distinct provided their elements have the
appropriate values. If the program attempts to modify such an array, the behavior is
undefined.
*p = 'a';
The problem is the above statement tries to modify the read only segment. String literal "Hello" resides in read only segment and can not be modified.
char str[] = "Hello";
The above statement copies Hello to str character array and the array contents can be modified.
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.