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)
What is the difference between char s[] and char *s?
(14 answers)
Closed 9 months ago.
I want to create void function that will change existing dynamic (or static) array. How this can be implemented in C and C++? How to properly pass arguments to such functions? For example i want to reverse char array
//function that reverse the string
void reverseString(char* str)
{
char t;
int i, j;
for (j = 0; str[j] != '\0'; j++)
{
}
j -= 1;
for (int i = 0; i < j; i++, j--)
{
t = str[i];
str[i] = str[j];
str[j] = t;
}
}
int main()
{
char* name = "Ani?321";
reverseString2(&name);
printf("%s", name);
}
running this code: Exception thrown at 0x796028BC (ucrtbased.dll) in Strings.exe: 0xC0000005: Access violation reading location 0x00E87B51.
When i changing function parameter from char* to char** -> Run-Time Check Failure #2 - Stack around the variable 'str' was corrupted. (pointing to the closing curly bracket of the main function)
You have two major problems:
Your pointer name is pointing to a literal string. Such strings can't be modified, and any attempt to do so leads to undefined behavior. You solve this issue by using an array instead:
char name[] = "Ani?321";
The second problem is that you pass a pointer to the pointer to your function. The type of &name (in your current code) is char **, which is not the correct type and definitely not the correct pointer. You should pass plain name as argument (which will also work when you solve the first problem).
Well, you have declared a string literal which you can't modify. Declare it like this instead char name[] = "Ani?321";
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)
Why is this string reversal C code causing a segmentation fault? [duplicate]
(8 answers)
Closed 4 years ago.
I'm attempting to remove duplicate characters from a string without using any additional buffer. The code works when I declare a single variable like this
char s[] = "aaabbb";
but not when I'm attempting to loop through a few test cases.
#include <stdio.h>
#include <string.h>
/* Design an algorithm and write code to remove the duplicate characters in a string
without using any additional buffer. NOTE: One or two additional variables are fine.
An extra copy of the array is not. */
void removeDuplicates(char s[]) {
// attempts to modify array in place without extra buffer
}
int main() {
char *s[4] = {"aaaa", "abcd", "ababab", "aaabbb"};
int i;
for (i = 0; i < 6; i++) {
removeDuplicates(s[i]);
}
return 0;
}
This returns Bus error: 10 because it's attempting to modify the string literal "aaaa" but I'm not sure how to overcome this while maintaining a nice setup for the test cases.
The s[i] are pointing to string literals, you need a 2-dimensinal char array like this:
char s[][7] = {"aaaa", "abcd", "ababab", "aaabbb"}
Also note that for a string of length n you need at least n+1 spaces because of the '\0'-termination."aaabbb"` has length 6, so it need at least 7 spaces.
Then you can do
int main() {
char s[][7] = {"aaaa", "abcd", "ababab", "aaabbb"};
size_t i;
for (i = 0; i < sizeof s / sizeof s[0]; i++) {
removeDuplicates(s[i]);
}
return 0;
}
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)
Why is this string reversal C code causing a segmentation fault? [duplicate]
(8 answers)
Closed 5 years ago.
#include<stdio.h>
#define ASIZE 50
void Reverse(char *str){
int Asize,i=0;
char temp;
// Find the length of the string
while(*(str+i)!='\0'){
i++;
}
Asize=i;
// string reverse
for(i=0;i<(Asize/2);i++){
temp = *(str+i);
//may be below is some error with first input method 1
//but for input method 2 it works perfectly
*(str+i) = *(str+(Asize-(i+1)));
*(str+(Asize-(i+1))) = temp;
}
}
int main()
{
//input method 1. (error aries while i pass the pointer as argument)
char *s = "abcxyz";
//input method 2 (works perfectly while as function parameter)
char s[ASIZE];
scanf("%s",s);
Reverse(s);
printf("%s",s);
}
In the main the input method 1 not working perfectly for the reverse of the string, but the method 2 works.
The concept of mine is not clear with the memory representation of char pointer. Maybe I am not good to make the question correctly but Would someone please make me clear why the method 1 is not working. Thanks in advance for the help.
"abcxyz" is actually a const char[7] type that can decay to a const char* in certain situations.
It is not a char* type; the behaviour on attempting to modify the string is undefined.
char s[ASIZE]; on the other hand is an array of char with automatic storage duration. You are free to modify any element of that as you please.
This question already has answers here:
Why is this string reversal C code causing a segmentation fault? [duplicate]
(8 answers)
Closed 5 years ago.
#include <stdio.h>
char *ft_strupcase(char *str);
char *ft_strupcase(char *str)
{
int i;
i = 0;
while (str[i])
{
if (str[i] >= 'a' && str[i] <= 'z')
{
str[i] -= 32;
}
i++;
}
return (str);
}
int main(void)
{
char *test = ft_strupcase("fdfFEhk");
for (int k = 0; test[k] != '\0'; k++)
{
printf("%c", test[k]);
}
return (0);
}
The expected result is to print the string passed to the function, all in capital letters. Instead, I get a bus error. Why and how can I fix this?
In your ft_strupcase() function, you're trying to modify the content of a string literal. This causes undefined behavior.
To quote the standard, C11, chapter §6.4.5/P7, String literals
[...] If the program attempts to modify such an array, the behavior is
undefined.
The argument you received is a string literal and you are not allowed to change the content. To avoid, you have to either
Pass a modifiable memory as the actual argument.
Inside the function, create a block (need to take care of the lifetime, either static storage or allocated via memory allocator functions), copy the content, perform the modify operations and return the address.
This is undefined behaviour as you are modifying string literal using ft_strupcase function
Rewrite your code to:
char source[] = "fdfFEhk";
char *test = ft_strupcase(source);
Now your string is not string literal anymore and is copied to RAM everytime source variable is initialized. Therefore, you have defined behaviour.
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)
Difference between declared string and allocated string
(3 answers)
Closed 8 years ago.
I have the following code. I initialized 2 pointers, one at the beginning and another at the ending of a string. After every step, I increment the 1st pointer and decrement the second pointer. I copy the value of first pointer into the second if the value obtained by dereferencing 1st pointer is less than the value obtained by dereferencing 2nd pointer.
#include <stdio.h>
#include <string.h>
int main() {
char *word="aacdbc";
char *p=word;
char *q=word+(strlen(word)-1);
printf("\n%s\n",word);
int i;
for(i=1;i<=strlen(word)-1;++i) {
if(*p<*q) {
*q=*p;
}
++p;
--q;
}
printf("\n%s\n",word);
return 0;
}
But the code shows a "Segmentation fault error". In which line did I make a mistake?
String literals in C (and C++) are immutable. So your attempt to change the string literal pointed to by the variable word
char *word = "aacdbc";
has undefined behaviour.
Change the definition from a pointer to an array
char word[] = "aacdbc";
The program could look the following way
#include <stdio.h>
int main( void )
{
char word[] = "aacdbc";
char *p = word;
char *q = word+ + sizeof( worrd ) - 1;
printf( "\n%s\n", word );
while ( p < q && p < --q )
{
if ( *p < *q ) *q = *p;
++p;
}
printf( "\n%s\n", word );
return 0;
}
Because word is a pointer to a constant (read-only) characters sequence. In other words, you can't change the contents of a string literal.
If you want to change its contents, you should declare word as an array of chars:
char word[]="aacdbc";
With that small change, the segfault should disappear.
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 *.