Can someone please explain to me why this code gives a Segmentation Fault:
char string[] = "this is a string";
char * string2 = "this is another string";
printf("%s\n",string );
printf("%s\n", string2);
printf("string[2]= %s, string2 = %s\n", string[2], &string2 );
It also gives the same error when I try to print
*string2 or *string2[2] or &string2[2]
I am really confused about this, likewise examples I see on websites seem to print but not this one.
The first two are fine but in the last one you probably want:
printf("string[2]= %c, string2 = %p\n", string[2], (void *)&string2 );
^ ^
You are getting a segmentation fault because you are tricking printf into interpreting a small integer (string[2]) as a pointer (that's what %s expects).
char * string2 = "this is another string";
declaration causes string2 point to t (first character of string) and that doesn't mean *string2 is entire string (On derefrencing string2),i.e, "this is another string". If you will try to print *string2 with %s, it will cause segmentation fault but with %c it will print t.
To print a pointer use %p specifier.
Related
Why is that the fourth line has an error?
char** h_addr_list = "Hello world";
char* s = "Hello world";
printf("%s\n", s);
printf("%s\n", *h_addr_list); // segmentation fault
Because when %s qualifier is given, printf function expects a pointer to NULL terminated character-string to be passed as the argument.
The h_addr_list itself is a pointer to NULL terminated character string.
The *h_addr_list is not.
So, these would work,
printf("%s\n", h_addr_list);
printf("%c\n", *h_addr_list);
I got this code:
const char *newLine = "\n";
printf('Content: %c\n', *newLine);
What happens now is a memory error.
Why is that happening?
The code crashes with a memory error (segmentation fault) because printf expects a null-terminated string as the first argument (i.e. a valid address pointing to some characters ending in a zero byte), but you are passing an (effectively random) integer to it which is not a valid address (unless you are very, very lucky :-).
As people commented, use double quotes to pass an actual string allocated by the compiler somewhere:
const char *newLine = "\n";
printf("Content: %c\n", *newLine);
Try this code
const char* newLine = "new Line";
printf("Content: %s\n", newLine);
So I tried this code
#include <stdio.h>
int main(void)
{
char string[] = "hello world";
char *my_ptr = string;
*my_ptr='Y';
printf("the first char of string is %c", *my_ptr);
}
OUTPUT_1 :-
the first char of string is Y
Now if I want to print the complete scentence in the string ("Yello world"). For that I changed 7th line to :-
printf("the whole string is %s", *my_ptr);
OUTPUT_2:-
Segmentation fault (core dumped)
But if I try changing it to this :-
printf("the whole string is %s", my_ptr);
OUTPUT_3 :-
the whole string is Yello world
Could someone please explain me why are the second case is failing ? AND
Why the third case prints correct ?
From my understanding *my_ptr (as well as my_ptr both) have the address of the first location, so why does the first one fail in printing a complete string , whereas the second one does well. Im a beginner so it would help if you could detail the reason behind such a behaviour in these cases.
my_ptr is of type char * it's a pointer on the first char of the string.
*my_ptr is of type char it's a character.
printf format string option %s takes a char *, it will loop over each character until it finds a string delimiter (0) :
First, *my_ptr, being Y
Then *(my_ptr + 1), being h
And so on...
When using printf with *my_ptr, The content of *my_ptr will be passed to printf as if it was a string pointer. Its value is 'Y' which is 89 in ascii.
printf will try to access the pointer at address 89 thinking it's a valid string pointer, but this address is most likely not readable and the kernel will kill the program trying to access memory it doesn't have access to.
This will work:
#include <stdio.h>
int main(void)
{
char string[] = "hello world";
char *my_ptr = string;
*my_ptr='Y';
printf("the first char of string is %c", *my_ptr);
printf("the whole string is %s", my_ptr);
}
my_ptr is a pointer to the entire string. *my_ptr is the value of the char at the beginning of the string.
printf("%s", char*)
printf("%c", char)
In the statement below:
printf("the whole string is %s", *my_ptr);
it will read the content from the address of *my_ptr. That produces Segmentation fault (core dumped) While in below:
printf("the whole string is %s", my_ptr);
The string will be read from the base address of string[ ]. To read the string you have to pass the base address from where character should be started to read untill '\0' character is found.
The reasaon is in C, %s is used for printing the string but u uses that to print the char which results in Core dump.
And in C, it is enough to give the base address to print the whole contents, no need to for using *addr.
If u want to access a particular character u can do so by *(a+0) for printing 1st char and *(a+1) for printin 2nd character and so on.
This:
printf("the whole string is %s", *my_ptr);
dereferences the pointer, so it passes a value of type char to printf(), which will then interpret it (due to the %s formatting specifier) as const char *, i.e. as a pointer to read-only character data. The value of a pointer is an address of a location in memory where some data is stored.
This will make printf() start reading characters from some very low address, where your program is not likely to be allowed to read. Thus the segmentation fault.
This question already has answers here:
How to replace specific characters in a string with other characters
(3 answers)
Closed 9 years ago.
I am trying to do something really basic on C but I keep getting a segmentation fault. All I want to do is replace a letter of a word with a different letter- in this example replace the l with a L. Can anyone help explain where I have gone wrong? It should be a really basic problem I think, I just have no idea why its not working.
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
char *string1;
string1 = "hello";
printf("string1 %s\n", string1);
printf("string1[2] %c\n", string1[2]);
string1[2] = 'L';
printf("string1 %s\n", string1);
return 0;
}
For my output I get
string1 hello
string1[2] l
Segmentation fault
Thanks!
string1 = "hello";
string1[2] = 'L';
You can't change string literals, it's undefined behavior. Try this:
char string1[] = "hello";
Or maybe:
char *string1;
string1 = malloc(6); /* hello + 0-terminator */
strcpy(string1, "hello");
/* Stuff. */
free(string1);
char *string1;
string1 = "hello";
string1 points to a string literal and string literals are non-modifiable.
What you can do is initialize an array with the elements of a string literal.
char string1[] = "hello";
the elements of string1 array are modifiable.
char *string1 = "hello";
When running the code, the string literal will be in a section that is read-only. OS does not allow the code to change that block of memory, so you get a seg-fault.
char string1[] = "hello";
The string literal will be pushed onto the stack when you run the code.
string1[2] = 'L';
you are trying to change a string literal which is undefined behavior in C.
Instead use string1[]="hello";
Segmentation fault you get is because the literal is probably stored in the the read only section of the memory and trying to write to it produces undefined behavior.
This one is probably very simple, but I can't seem to get it working.
I have this very simple snippet of code:
#include <stdio.h>
#include <string.h>
int main(void)
{
char buf[100];
char *p = buf;
strcpy(p, "Test string");
printf("%s\n", *p);
}
Which causes a segmentation fault when I run it. GDB outputs:
Program received signal SIGSEGV, Segmentation fault.
0xb76af3b3 in strlen () from /lib/i686/cmov/libc.so.6
But I still don't get it.
Comments would be appreciated, thanks.
When you write
printf("%s\n", *p);
the *p will be the value at p[0] which is a character. The printf however is looking for an array of chars, thus causing it to segfault. Remember that in C, strings are just arrays of characters, and arrays are effectively pointers to the first element, this is why you don't need to dereference.
To fix this remove the * to get:
printf("%s\n", p);
You're passing a character to printf; you should be passing the pointer.
char buf[100];
char *p = buf;
strcpy(p, "Test string");
printf("%s\n", p); // p, not *p
Use this:
printf("%s\n", p);
use "p" instead of "*p"
Replace
printf("%s\n", *p);
with
printf("%s\n", p);
When you use %s, printf expects you to pass a char*. You are passing a char instead.
just pass the string(the pointer):
printf("%s\n", p);
If you want to print the first char, then:
printf("%c\n", *p);
%s causes printf() to dereference *p. Suppose the string was "Test string".
Then on my Solaris sparc box: (in a test program) p would be "aimed at" the address 0x54657374. The probability of that particular address being part of your process space is next to zero.
That is what caused the SIGSEGV signal (segfault).