Replacing a character in string - c

#include <stdio.h>
#include <string.h>
void replace (char a[]){
char *y;
*y = 'm';
char *p = a;
p = strchr(p, 'g');
while (p){
*p = *y;
p++;
p = strchr(p, 'g');
}
}
int main (){
char x[10];
gets(x);
replace(x);
puts(x);
return 0;
}
What's wrong with this replace function?
It doesn't output a string instead it says segmentation fault.

You're trying to write to a wild pointer here:
char *y;
*y = 'm';
y doesn't point anywhere in particular, so you get Undefined Behaviour (a seg fault in your particular case).

You are assigning value using an uninitialized pointer, y.
Why do you use pointer y anyway, instead of
*p = *y;
you can just say
*p = 'm';

y is not allocated. It is just a pointer and a pointer must point to a space in the memory. But you didn't allocate any space in the memory. So when you defferentiate it, is going to deferentiate the garbage address that a non itialized pointer has. Crash...
So rather than
char *y;
*y='p';
just write:
char y='p'; ///no pointer
Then a first improvment at the function. The function is too specific, just for a character, I would write like:
void replace (char a[],char from, char to)
{
char *p = a;
while(*p)
{
if(*p==from) *p=to;
p++;
}
}

If you compile your program with warnings enabled you should get a warning like this (with the GCC compiler):
warning: ‘y’ is used uninitialized in this function [-Wuninitialized]
*y = 'm';
^
Before you dereference the pointer y you need to know that it points to a valid object, but in your case y has not been assigned a value so it can point anywhere. Also you don't need any extra pointer; here is a more concise (and more general) version of the function:
static void replace(char old, char new, char s[])
{
s = strchr(s, old);
while (s != NULL) {
*s = new;
s = strchr(s, old);
}
}
Or without using strchr:
static void replace(char old, char new, char s[])
{
int i = 0;
while (s[i] != '\0') {
if (s[i] == old) {
s[i] = new;
}
i++;
}
}

Related

segmentation fault when returning string from function

I was wondering what this code should print. I wanted to check whether it prints we can, can we or we can, but instead i got segmentation fault.
Here is the code:
char* mysubstr() {
char* x = "Yes we can, can we";
char* y = "we can";
char* tmp = x;
while(*tmp) {
if (*tmp == *y)
return *tmp;
tmp++;
}
return x;
}
void main() {
printf("%s", mysubstr());
}
I think the wrong part is the return *tmp;, but why? What's wrong with that?
Your compiler basically already told you what is wrong:
return makes pointer from integer without a cast
This is because you define a function returning a char * but you return a char.
With char *tmp = x; you define a pointer and in your return statement you dereference it.
Hence you return (char*)'w'
If you use that return value for printf value 'w' is taken an address which causes your crash.
You should just do return tmp;
This is not the only issue in your code.
Your function name indicates you want to make some substring function.
Bur your code returns immediately it found a match of first letter in second string. You don't verify if the other character also are same.
Following works:
char* mysubstr()
{
char* x = "Yes we can, can we";
char* y = "we can";
char* tmp = x;
while(*tmp)
{
if(*tmp == *y)
{
return (char*) tmp;
}
tmp++;
}
return (char*) x;
}
int main()
{
printf("%s", mysubstr());
return 0;
}
And the answer is:
**We can, can we**

Segmentation Fault while malloc and sizeof

Sorry if I'm offending anyone but I started learning C this week and I got a segmentation fault while compiling this. Can I please have a second pair of eyes to help me with this error?
void Space(void *empty, size_p s)
{
empty = malloc(s);
}
int main()
{
int *p = NULL;
Space(p, sizeof(p));
*p = 7;
return;
}
empty is just a pointer variable - it contains "some" address, but it is still a local variable in the context of Space. If you want to update the value of int *p in Space, you'll need to pass a pointer to it:
int main()
{
int *p = NULL;
Space(&p, sizeof *p);
*p = 7;
return;
}
void Space(void **empty, size_p s)
{
*empty = malloc(s);
}
Also, you have a bug where you call Space: Space(p, sizeof(p));
sizeof(p) is the size of the int * variable but you want to allocate the size of an int as that's what you're storing in p. So that line should instead be:
Space(&p, sizeof *p);
void * Space(void *empty, size_t s)
{
empty = malloc(s);
return empty;
}
int main()
{
int *p = NULL;
p = Space(p, sizeof(int));
*p = 7;
return 0;
}
You can change the Space function to return a void * or an int *. The variable empty is a copy of the pointer in main. When you change the value in Space, because it is a copy, the change never makes it back to main.
I changed sizeof(p) to sizeof(int). This is more of personal preference but I try to only give types as the argument to sizeof. You can get surprising results when you apply sizeof to variables.
I really like #DIMMSum's answer but I know pointer-to-a-pointer can be confusing especially when starting out.

char pointer and printf 2

please advise me on the following output:
int main()
{
char ***x = "jjhljlhjlhjl";
char ***q = "asddfwerwerw";
**q = **x;
printf("x:%s\n",x);
printf("q:%s\n",q);
}
Output: 1 Segmentation fault
This is what you should have:
#include <stdio.h>
int main(void) {
char *x = "jjhljlhjlhjl";
char *q = "asddfwerwerw";
q = x;
printf("x:%s\n",x);
printf("q:%s\n",q);
return 0;
}
If you want to initialize a character string, use char *x
Don't use ***x. That means pointer to pointer to pointer to a char.
Hope that helps.
"Segmentation fault" is not an output, it's an indication that your program has crashed.
This should come as no surprise, because string literals are char*, not char***. Trying to double-derefefence such pointers is undefined behavior, because it re-interprets the content of a string literal as a pointer to char. This is what is causing the crash.
You can modify your program as follows to make it legal:
int main() {
char *x = "jjhljlhjlhjl";
char tmp[] = "asddfwerwerw";
char *q = tmp;
*q = *x;
// This will produce an output that should be easy to explain:
printf("x:%s\n",x);
printf("q:%s\n",q);
}

return from a function which changes pointer address, address stays the same

I wrote a more complex program but I have narrowed down my problem to the following one:
Why is this program printing down junk and not hzllo? I have followed the values and memory address of temp and p with the debugger and it returns from the foo function correctly and for a reason I don't understand prints junk.
void foo(char **str) {
char temp[79];
strcpy_s(temp,79,*str);
*(temp + 1) = 'z';
*str = temp;
}
void main() {
char *p = (char*) malloc(79 * sizeof(char));
p = "hello";
foo(&p);
printf("%s", p);
}
Change
char temp[79]; # allocated on the stack, vanishes on return
...to...
static char temp[79]; # has a longer lifetime
Also, you don't need the malloc(3).
temp is a local variable, which goes out of scope when you exit foo. Thus p is a dangling pointer and your program has undefined behaviour.
void foo(char **str) {
// Bad: "temp" doesn't exist when the function returns
char temp[79];
strcpy_s(temp,79,*str);
*(temp + 1) = 'z';
*str = temp;
}
void main() {
char *p = (char*) malloc(79 * sizeof(char));
p = "hello";
foo(&p);
printf("%s", p);
}
This is better:
void foo(char **str) {
// This should change the pointer ... to something valid outside the function
*str = (*str) + 1;
}

C segmentation fault-char pointers

I need help figuring out why I am getting a segmentation fault here. I have gone over it and I think I am doing something wrong with the pointers, but I can figure out what.
My Program:
#include <stdlib.h>
#include <stdio.h>
void encrypt(char* c);
//characters are shifted by 175
int main(){
char* a;
*a = 'a';
/*SEGMENTATION FAULT HERE!*/
encrypt(a);
printf("test:%c/n",*a);
return 0;
};
void encrypt(char* c){
char* result;
int i=(int)(*c);
i+=175;
if(i>255)
{
i-=256;
}
*c=(char)i;
};
The problem is here:
char *a;
*a = 'a'
Since the variable "a" is not initialized, *a = 'a' is assigning to a random memory location.
You could do something like this:
char a[1];
a[0] = 'a';
encrypt(&a[0]);
Or even just use a single character in your case:
int main(){
char a = 'a';
encrypt(&a);
printf("test:%c/n",a);
return 0;
};
char* a;
*a = 'a';
/*SEGMENTATION FAULT HERE!*/
There isn't any "there" there. You've declared a and left it uninitialized. Then you tried to use it as an address. You need to make a point to something.
One example:
char buffer[512];
char *a = buffer;
(Note buffer has a maximum size and when it falls out of scope you cannot reference any pointers to it.)
Or dynamic memory:
char *a = malloc(/* Some size... */);
if (!a) { /* TODO: handle memory allocation failure */ }
// todo - do something with a.
free(a);
That pointer a does not get the actual space where to store the data. You just declare the pointer, but pointing to where? You can assign memory this way:
char *a = malloc(1);
Then it won't segfault. You have to free the variable afterwards:
free(a);
But in this case, even better,
char a = 'a';
encript(&a);

Resources