This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why do I get a segmentation fault when writing to a string?
The following simple function should reverse a character array in place.
void reverse(char* str)
{
char* last = str;
// find end of the string
while(*last) {
++last;
}
// swap characters until the pointers meet in the middle
while(str < last)
{
--last;
char temp = *str;
*str = *last;
*last = temp;
++str;
}
}
int main()
{
char* a= "Hello";
reverse(a);
return 0;
}
The code compiles. But it throws a runtime error about access violation. According to the debugger the culprit is the line below:
char temp = *str;
Any ideas why it happens?
char* a= "Hello";
The pointer a points to a string literal. According to the standard, attempting to modify a string literal results in undefined behaviour. In the case of your implementation, the segmentation fault indicates that the compiler is choosing to place the string literal in non-modifiable memory.
Declare a to be a string that is modifiable. For example, like this:
char a[] = "Hello";
Related
This question already has answers here:
Access violation writing location when working with pointers to char
(4 answers)
Closed 5 years ago.
I'm trying to implement tolower(char *) function, but I get access violation error. I came to know that this is because to compiler stores string literals in a read-only memory. Is this true?
Here's some code:
char* strToLower(char *str)
{
if(str == nullptr)
return nullptr;
size_t len = strlen(str);
if(len <= 0)
return nullptr;
for(size_t i = 0; i < len; i++)
*(str+i) = (char)tolower(*(str+i));//access violation error
return str;
}
int main()
{
char *str = "ThIs Is A StRiNgGGG";
cout << strToLower(str) << endl;
system("pause");
return 0;
}
If this is true, how am I supposed to implement such function?
Yes, it's true. You cannot modify a string literal. In fact, if your compiler were not from 1922 it would have prevented you from even obtaining a non-const pointer to a string literal in the first place.
You didn't state your goals, so when you ask "how am I supposed to implement such function" it's not really clear what you want to do. But you can make a copy of the string literal to get your own string, then modify that as you please:
// Initialises an array that belongs to you, by copying from a string literal
char str[] = "ThIs Is A StRiNgGGG";
// Obtains a pointer to a string literal; you may not modify the data it points to
const char* str = "ThIs Is A StRiNgGGG";
// Ancient syntax; not even legal any more, because it leads to bugs like yours
char* str = "ThIs Is A StRiNgGGG";
Of course, since this is C++, you should not be using C-strings in the first place:
std::string str("ThIs Is A StRiNgGGG");
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 8 years ago.
problem is in 15 and 16th line
i am unable to store char into
a pointer pointing to a string.
the problem is same as given in
my book.?do i need to change my
compiler dev c++?
plz help.
#include<iostream>
#include<conio.h>
using namespace std;
void reverse(char *str)
{
char *end=str;
char *beg=str;
char temp;
while(*end)
{
end++;
}
end--;
while(beg<end)
{
cout<<*beg<<" , "<<*end<<endl;
temp=*beg;
*beg=*end;
*end=temp;
beg++;
end--;
}
cout<<str;
}
int main()
{
char *str="saurabh";
reverse(str);
getch();
return 0;
}
char *str="saurabh";
You cannot manipulate "saurabh" because it is literal.
For this you should either copy it to char[],
Example,
char arr[20];
char *ptr = "Data";
strcpy(arr,ptr);
I know that you likely need to implement yourself reverse, but you can use std implementation for tests:
std::string s("abc");
std::reverse(s.begin(), s.end());
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 am new to C/C++, I'm trying to learn it, I have created the following function but it throws an exception, when I'm trying to assign the uppercase value to *string: Unhandled exception at 0x00411820 in CPP1.exe: 0xC0000005: Access violation writing location 0x00417754.
void ToUpper(char* string)
{
while(*string != '\0')
{
if(*string >= 97 && *string <= 122)
{
int symbol = *string;
*string = symbol - 32;
}
string++;
}
}
Usage:
char* x = "text";
ToUpper(x);
Could you please help me?
change
char* x = "text";
to
char x[] = "text";
DONE
Never try to change a const character string. Always use character arrays for this sort of manipulation.
Memory for "text" will be allocated in .readonly section.
char* x = "text";
Tyring to alter read-only section is undefined behaviour.
use gcc -S filename.c to view the assembly code. This gives you more idea about whereabouts of "text".
Like others suggested, I suggest to use char x[] = "text" instead.
main()
{
char *a = "text";
char *x = malloc(strlen(a)+1);
strcpy(x,a);
ToUpper(x);
// ToUpper(a); // Fails
printf("%s %s\n",a,x);
}
Output: text TEXT
ToUpper(a) fails, because the string is replaced in a protected memory area (in the middle of the code most likely, as at least 64-bit x86-processors have [rip] -relative addressing mode, which makes it lucrative to place data in between code lines...
Also char x[]="text"; works, because now the complete array of x is placed in the stack. In case of char *x = "text"; only the pointer is placed on stack, but the content points to restricted (read-only) memory.
It is an error to try to modify a string literal by a pointer:
void f()
{
char * p = "Naee";
p[2] = 'm'; // error: assignment to const; result is undefined
}
Having string literals constant allows for significant optimizations in the storage allocation and access. If you want a string that you can modify
modify, you must copy the characters into an array:
void f()
{
char p [] = "Eero";
p [0] = 'Z'; // ok
}
You can use like this no need to create symbol varible
*string=*string-32;
but pass array to the function in calling environment rather passing string literal
so
char * str[] ="hello";
ToUpper(str);
You have to type cast the value in the assignment statement.
*string = *(char *)symbol - 32;
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do you reverse a string in place in C or C++?
Why is this C code causing a segmentation fault?
Modifying value of char pointer in c produces segfault
Running a very simple code example
#include <stdlib.h>
#include <iostream>
char* last_char(char* s){
char* last = s;
while (*last) ++last;
return last;
}
char* in_place_reverse(char* s) {
char* left = s;
char* right = last_char(s);
char temp;
while( left < right ) {
temp = *left;
*left = *right;
*right = temp;
left++;
right--;
}
return s;
}
int main(){
char * s = "letters\n";
std::cout << in_place_reverse(s);
}
All the time I get
Segmentation fault
But from my point of view I'm not doing anything illegal within the code.
Please help me to determine what's wrong.
P.S. I compile with
g++ example.c
Two problems:
You are trying to modify a string literal. This may work, it may not, or it may crash. This is invoking undefined behavior. Use char s[] = "letters\n" to make a mutable copy.
last_char() in fact returns a pointer to the sentinel '\0' at the end of the string -- it points beyond the last character. Change return last to return last - 1. Otherwise you are going to move the sentinel around too, and that's almost certainly not what you want. (Note that this will return a pointer to garbage if the string is zero-length. You should fast-succeed in in_place_reverse() if *s == '\0' to avoid this complexity.)
You are modifying a string literal and string literals are non-modifiable.
Use char s[] = "letters\n"; instead
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why is this C code causing a segmentation fault?
char* string = "abcd";
now when i try to change some character of this string i get segmentation fault
*string = 'p';
or
string[0] = 'p';
string[0] = 52;
Can someone please explain me the reason that why is it happening.
Thanks
Alok.Kr.
If you write char* string = "abcd"; the string "abcd" is stocked into the static data part of your memory and you can't modify it.
And if ou write char* string = 'p';, that's just wrong. First, you try to declare a variable with the same name (string) and, worse, you try to assign a char value to a char pointer variable. This doesn't work. Same thing : char[0] = 'p'; really means nothing to your compiler except a syntax error.
String literals are non-modifiable in C. This has been asked and answered many times before, though it isn't too easy to search for.
If you want to modify string, declare it as an array, not a pointer to a string literal.
#include <stdio.h>
int main()
{
char string[] = "hello world";
string[0] = 'H';
string[6] = 'W';
printf("%s\n", string);
return 0;
}
Results in:
$ /tmp/hello
Hello World