This question already has answers here:
What is the difference between char s[] and char *s?
(14 answers)
Closed 9 years ago.
void main() {
char *x;
x="abc";
*x='1';
}
Why it comes with error "Access violation writing location"?
I cannot assign value to x by *x='1'?
Modifying string literals leads to undefined behavior, try using char arrays instead:
int main() {
char x[] = "abc";
*x ='1';
}
Also note you should use int main().
Or if you prefer to use pointers, use this a little redundant example:
int main() {
char x[] = "abc";
char *y = x;
*y ='1';
}
Thats wrong because you are attempting to modify a string literal. It is created in readonly mode and if you will try to change that then it would be an access violation and hence result in error.
As a solution as to how it can be achieved you can try using char arrays
The application is loaded in several memory regions (memory pages), code read-only executable (program counter can run in it), and string literals might ideally go into a read-only region.
Writing to it would give an access violation. In fact is nice that you get that violation, are you running Windows? That would possitively surprise me.
Related
This question already has an answer here:
Is modification of string literals undefined behaviour according to the C89 standard?
(1 answer)
Closed 7 years ago.
So I've been playing around with C lately and have been trying to understand the intricacies of passing by value/reference and the ability to manipulate a passed-in variable inside a function. I've hit a road block, however, with the following:
void modifyCharArray(char *input)
{
//change input[0] to 'D'
input[0] = 'D';
}
int main()
{
char *test = "Bad";
modifyCharArray(test);
printf("Bad --> %s\n", test);
}
So the idea was to just modify a char array inside a function, and then print out said array after the modification completed. However, this fails, since all I'm doing is modifying the value of input that is passed in and not the actual memory address.
In short, is there any way I can take in a char *input into a function and modify its original memory address without using something like memcpy from string.h?
In short, is there any way I can take in a char *input into a function and modify its original memory address without using something like memcpy from string.h?
Yes, you can. Your function modifyCharArray is doing the right thing. What you are seeing is caused by that fact that
char *test = "Bad";
creates "Bad" in read only memory of the program and test points to that memory. Changing it is cause for undefined behavior.
If you want to create a modifiable string, use:
char test[] = "Bad";
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[]
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why does this Seg Fault?
What is the difference between char a[] = “string”; and char *p = “string”;
Trying to understand why s[0]='H' fails. I'm guessing this has something to do with the data segment in the process memory but maybe someone better explain this?
void str2 (void)
{
char *s = "hello";
printf("%s\n", s);
s[0] = 'H'; //maybe this is a problem because content in s is constant?
printf("%s\n", s);
}
int main()
{
str2();
return 0;
}
It's wrong because the C standard says that attempting to modify a string literal gives undefined behavior.
Exactly what will happen can and will vary. In some cases it'll "work" -- the content of the string literal will change to what you've asked (e.g., back in the MS-DOS days, it usually did). In other cases, the compiler will merge identical string literals, so something like:
char *a = "1234";
char *b = "1234";
a[1] = 'a';
printf("%s\n", b);
...would print out 1a34, even though you never explicitly modified b at all.
In still other cases (including most modern systems) you can expect the attempted write to fail completely and some sort of exception/signal to be thrown instead.
You are trying to modify a string literal, which resides in implementation defined read only memory thereby causing an Undefined Behavior. Note that the undefined behavior does not warrant that your program crashes but it might show you any behavior.
Good Read:
What is the difference between char a[] = ?string?; and char *p = ?string?;?
I think this behavior, a good or stern compiler should not allow since this is (char *s = "hello") pointer to constant i.e. modifying the contents will lead to undefined behavior if the compiler will not throw any error on this
Given the following code:
#include "stdafx.h"
#include "string.h"
static char *myStaticArray[] = {"HelloOne", "Two", "Three"};
int _tmain(int argc, _TCHAR* argv[])
{
char * p = strstr(myStaticArray[0],"One");
char hello[10];
memset(hello,0,sizeof(hello));
strncpy(hello,"Hello",6);
strncpy(p,"Hello",3); // Access Violation
return 0;
}
I'm getting an access violation at precisely the point when it attempts to write to the address of myStaticArray[0].
Why is this a problem?
Background: I'm porting old C++ to C# as primarily a C# developer, so please excuse my ignorance! This piece of code apparently wasn't an issue in the old build, so I'm confused...
char * p = strstr(myStaticArray[0],"One");
p points to a part of the string literal "HelloOne". You mustn't try to modify string literals, that's undefined behaviour.
Often, string literals are stored in a read-only part of the memory, so trying to write to them causes a segmentation fault/access violation.
static char *myStaticArray[] = {"HelloOne", "Two", "Three"};
The strings in the array are string literals and are non-modifiable in C and in C++.
strncpy(p,"Hello",3);
This function call attempts to modify a string literal.
Another issue is your use of the strncpy function which does not always null terminate the string. This is the case here because strlen("Hello") is greater than 3 (your last strncpy argument).
If you want to be able to modify the strings then you'll need to allocate the character arrays like this
static char myStaticArray[][25] = {"HelloOne", "two", "three"};
The problem, as others stated is that your method causes the compiler create an array of 3 pointers to constant strings. The above declaration creates a two dementional character array, then copies the constant-string data to that memory.