thread 1 exc_bad_access (code=1 address=0x0) - c

I'm working on a project where I have to replace some char in a string.
I do not understand one of the errors I see.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void replaceLetters(char *text, char original, char new_char);
{
for (int counter = 0; text[counter] != '\0'; counter++)
{
if (text[counter] == original)//Error occurs here
{
text[counter] = new_char;
}
printf("%c", chr[counter]);
}
return 0;
}
int main()
{
char *text = "HallO";
char original = 'O';
char new_char = 'N';
replaceLetters(text, original, new_char);
return 0;
}
At the if statement the following error occurs: thread 1 exc_bad_access (code=1 address=0x0).
What does this mean, and how can I address it?

In c, string literals like "HallO" are stored in global read-only memory. If you want to modify the string, you will need to keep it in a buffer on the stack.
char text[6] = "HallO";

"What does this mean, and how can I address it?"
It is an access violation. The string you have defined
char *text = "HallO";
is referred to in C as a string literal, and is created in an area of read-only memory, resulting in an access violation.
This can be easily addressed by creating the original variable such that it is editable. eg:
char text[6] = "HallO"; //okay
char text[] = "HallO"; //better, let the compiler do the computation
char text[100] = "HallO"; //useful if you know changes to string will require more room

Related

"initializer element is not constant char" error in C

Here is my code:
#include <stdio.h>
#include<stdlib.h>
char *s = (char *)malloc (40);
int main(void)
{
s="this is a string";
printf("%s",s);
}
I am getting the following error:
error: initializer element is not constant char *s = (char *)malloc
(40);
You don't need to allocate memory in this way if you wanna initialize it in code, I mean:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *s = "this is a string"; // char s[] = "this is a string";
printf("%s",s);
return 0;
}
is just enough in this case. If you really want to assign const char string to your char array, this topic should enlighten you: Dynamically allocating memory for const char string using malloc()
You cannot not do that.
You can do this instead -
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
char *s; // probably should avoid using global variables
int main(void)
{
s=malloc(40);
strcpy(s,"this is a string");
printf("%s",s);
free(s);
}
Other than this inside main you can do this -
char *s="this is a string"; //string literal you can't modify it
Or
char s[]="this is a string"; // modifiable string
You assign a pointer to a string constant to a variable, s, which is not declared to point to a constant. This is what you want:
#include <stdio.h>
int main(void)
{
const char *s = "this is a string";
printf("%s\n", s);
return 0;
}
In C there are basically three ways to declare "string" variables.
String constant pointers
If you need a name for a string that will not change, you can declare and initialize it like
const char *s = "a string";
Character arrays
If you need a string variable and you know in advance how long it needs to be you can declare and initialize it like
char s[] = "a string";
or like
char s[9];
strcpy(s, "a string");
Character sequence pointers
If you don't know in advance how large the array needs to be, you can allocate space during program execution:
char *s;
s = malloc(strlen(someString) + 1);
if (s != NULL) {
strcpy(s, someString);
}
The "+1" is to make room for the null character (\0).

Why is this code getting a segmentation fault?

I am trying to write a function that deletes a char c from a string src, and I am getting a seg fault when I try to run it. Here is the function.
void removeChar(char *src, char c){
int i, j = 0;
int size;
char ch1;
char str1[100];
size = strlen(src);
for (i = 0; i < size; i++){
if (src[i] != c){
ch1 = src[i];
str1[j] = ch1;
j++;
}
}
str1[j] = '\0';
src = str1;
}
And here is the main function where I am calling it.
int main(int argc, char **argv){
char *str = "Hello, world!\0";
printf("%s\n", removeChar(str, 'l'));
}
the return type of this function removeChar(str, 'l') is void not an char array and you are passing this to
printf("%s\n", removeChar(str, 'l'));
so here %s may give you the segmentation fault.
You assigned pointer src by the address of the first element of a local array
src = str1;
that will be destroyed after exiting the function. Moreover variable src is a local variable of the function so any changes of it do not influence the original pointer str.
Take into account that you may not change string literals. Any attempt to change a string literal results in undefined behaviour of the program.
Also the function has return type void and may not be used as an outputed object in function printf.
Type void is an incomplete type. It has no values.
And there is no need to append explicitly terminating zero to a string literal as you did.
"Hello, world!\0"
String literals already have terminating zeroes. So you could write simply
"Hello, world!"
As I already answered this question then you can visit my personal forum where there is a realization of the corresponding valid function.
If to declare correctly the function like
char * removeChar( char *s, char c );
then the main will look the following way
int main(int argc, char **argv)
{
char str[] = "Hello, world!";
printf( "%s\n", removeChar( str, 'l' ) );
}
You can print the string in the function itself! Then it works:
#include <stdio.h>
#include <string.h>
void removeChar(char src[], char c){
int i, j = 0;
int size;
char ch1;
char str1[100];
size = strlen(src);
for (i = 0; i < size; i++) {
if (src[i] != c) {
ch1 = src[i];
str1[j] = ch1;
j++;
}
}
str1[j] = '\0';
src = str1;
printf("%s\n", src);
}
int main(int argc, char **argv) {
char str[] = "Hello, world!";
removeChar(str, 'l');
return 0;
}
You have several bugs:
char *str = "Hello, world!\0";. Setting a non-constant pointer to point at a string literal is always wrong. Instead, declare the variable as const char *str. See this FAQ.
removeChar doesn't return anything so you can't pass it as a parameter to be printed by printf. Your compiler really should have complained here. Chances are that your compiler is misconfigured or you you aren't using it with all warnings enabled.
char str1[100]; You cannot use local variables and then try to pass the contents on to the caller. See this FAQ.
src = str1; doesn't do a thing, since src is only a local copy of the original pointer. With this assignment, you will not change the address of str in main. Which would have been a bug anyway, because of 3) above. You should rewrite your program so that is only uses src and no temporary array.
Not have enough reputation to comment. So, I had to write this on answer:
As Vlad from Moscow pointed out,
`a local array do not exist after the function terminate`
I suggest you obey the same principle as of standard library functions. If you didn't already notice,none string.h function allocate memory for the user. You must allocate before call.
char *str = "Hello, world!\0";
The above code do not guarantee a modifiable memory. The compiler can set them in read only memory. You should use a array instead.

Error with mystrlen function

I was trying to write out some of the implementations of the string functions available in C. My code is:
#include <stdio.h>
#include <stdlib.h>
char *mystrcpy(char *s1, char *s2)
{
while(*s1++ = *s2++);
return s1;
}
int mystrlen(char *s)
{
int len = 0;
while(*s != '\0')
{
len++;
}
return len;
}
int main(void)
{
char arr = "Hi";
char arr1[10];
char arr2[] = "Hello";
int length;
mystrcpy(arr1, arr2);
printf("%s", arr1);
length = mystrlen(arr);
printf("%d", length);
return 0;
}
mystrcpy works fine, but the other method mystrlen does no execute. What could be the error? The following is the program termination note:
Process terminated with status -1073741510 (0 minutes, 4 seconds)
Also, there are few warnings related to casts. Is there any place in the code where I should be using any cast?
First, your mystrlen has an infinite loop.
Fixed code:
int mystrlen(const char *s)
{
int len = 0;
while (*s++ /* increment to next character every loop */ != '\0')
{
len++;
}
return len;
}
Also added const since you never change the data referred to by *s
Second, the assignment: char arr="Hi"; is not valid.
You are attempting to assign a char[] array to a char variable. The correct form would be one of the following:
char arr[]="Hi"; // array syntax
char *arr="Hi"; // pointer syntax
Given your invalid arr assignment, your runtime error is most likely caused by mystrlen attempting to incorrectly deference arr.
What compiler are you using? Most conforming compilers should have caught the second issue. If using GCC, add the -Wall flag to your makefile.
This:
char arr="Hi"; /* Should have caused compiler warning,
as is attempting to assign a char
to a char[3]. */
should be:
char arr[] ="Hi";
or:
char* arr = "Hi";

How do you assign substrings in C?

I'm trying to figure out why this doesn't work:
#include <stdio.h>
int main ()
{
char *orig = "Hey you guys.";
char *str;
str = &orig;
while(*str++) {
if (*str == 'y')
*str = '#';
}
puts(orig);
return 0;
}
// OUTPUT => "Hey you guys."
// Not "he# #ou gu#s." as expected.
By assigning str = &orig, I thought that str would share the same memory address as orig.
What am I missing?
(1) for sharing memory you want to do str = orig, since str is already a pointer type.
(2) orig is defined as a string literal, a constant - so you cannot modify the value "Hey you guys.", even not when accessing it via str, it will result in a run time error.
EDIT: Issue #3: In your while loop, you first increase the pointer, and only then checks if it is 'y' and modify. By doing so - you will miss the first element. "yasdf" will become "yasdf" and not "#asdf", as you expect. [well I think that what you expect anyway...]
To achieve what you are after, you can follow this: [using strcpy and a buffer, to avoid writing on constant memory]
#include <stdio.h>
#include <string.h>
int main ()
{
char *orig = "Hey you guys.";
char buff[14]; //the length of orig + 1 byte for '\0'
char *str = buff; //since str and buff are already pointers
strcpy(str,orig);
while(*str) {
if (*str == 'y')
*str = '#';
str++;
}
puts(buff);
return 0;
}
Two things:
&orig is the address of the pointer. Perhaps you want str = orig. Your compiler should have warned you about a pointer type mismatch here; if it didn't, then turn up the warning level until it does.
Modifying a constant literal string won't always work. Use char orig[] = "Hey you guys.", which copies the literal string into an array called orig that you can safely modify.
you miss the first element
you cannot change a string literal
Modified code:
#include <stdio.h>
int main ()
{
char orig[] = "Hey you guys.";
char *str;
str = orig;
int i;
while(*str){
if (*str == 'y')
*str = '#';
*str++;
}
puts(str);
puts(orig);
return 0;
}

Bus error in a simple C program

I am trying to reverse a C style string using the following simple program.
#include "stdio.h"
void reverse (char * str);
int main (int argc , char* argv[]){
char *str = "hello";
reverse(str);
return 0;
}
void reverse (char *str)
{
char *end = str;
char tmp;
if(str){
while(*end){
++end;
}
--end;
while(str < end){
tmp = *str;
*str++ = *end;
*end-- = tmp;
}
}
}
I can't figure out why I get a "bus error" when I try to run the above program. I am using i686-apple-darwin10-gcc-4.2.1. Thanks
If you change char *str = "hello"; to char str[] = "hello"; your error will go away, since string literals are stored in a read-only part of memory and trying to modify "hello" may cause your program to crash (as it does in this case).
Declaring str as a char[] will copy the literal "hello" into a non-const buffer that you can modify the contents of.
String literals in C are stored in the .data section of the binary which is read only memory. When saving it as const char * or char * they are non modifiable (in some cases if you modify the access fails silently or in your case you get a bus error because it's ROM).
Try using char str[] = "hello"; instead (I believe this should work, but I may be wrong).

Resources