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).
Related
In the following c code the 'line 10' doesn't print anything when ln8 & lb9 are removed. It just takes the input and prints nothing. But the weird thing is on addition of those 2 lines, the code works perfectly fine i.e the input string got printed twice once by for loop and once by the printf statement in ln10. (What i am trying to do is just print the input String)
I use MinGw Compiler and ran code using cmd.enter image description here
int main()
{
char *s;
scanf("%s",s);
printf("Line 9:\t");
for(int i=0;s[i]!='\0';i++) //line 8
printf("%c",*(s+i)); //line 9
printf("\nLine 12:\t%s\n",s); //line10
return 0;
}
char *s
you declare a pointer but do not allocate for it. It's undefined. Because the undefined behavior, everything can happen. (for example, When i test your program in my PC, it raises Segmentation fault (core dumped)
You have to allocate for the pointer before scanf (do not forget to free s when you do not need to use it):
char *s = malloc(sizeof(char) * MAX_LEN); // MAX_LEN: you define its value.
Or you can use the array of character:
char s[100]; // here, the string length is up to 99;
Try initializing the s using strdup.
int main()
{
char *s = strdup("");
scanf("%s",s);
printf("\nLine 12:\t%s\n",s); //line10
return 0;
}
I am trying to perform a simple string manipulation (strcat) on a char array. I tried 2 approaches.
In the first case, I am allocating memory to a char* and then assigning the value through scanf() .
This approach is working fine.
void fun1(char** s1) {
char temp[15] = "&Superman";
printf("inside fun1 %s %s\n",(*s1),temp);
strcat((*s1),temp);
}
int main()
{
char *str;
str = malloc(sizeof(char)*15);
scanf("%s",str);
fun1(&str);
printf("1st string %s\n",str);
return 0;
}
The O/p is as expected for this case
Batman
inside fun1 Batman &Superman
1st string Batman&Superman
In the second approach , I am assigning value to str directly in the main() without scanf().
void fun1(char** s1) {
char temp[15] = "&Superman";
printf("inside fun1 %s %s\n",(*s1),temp);
strcat((*s1),temp);
}
int main()
{
char *str;
str = malloc(sizeof(char)*15);
str = "Batman";
fun1(&str);
printf("1st string %s\n",str);
return 0;
}
In this case I am getting segmentation fault inside fun1() while strcat is getting executed.
inside fun1 Batman &Superman
Segmentation fault (core dumped)
GDB o/p from OnlineGDB
(gdb) r
Starting program: /home/a.out
inside fun1 Batman &Superman
Program received signal SIGSEGV, Segmentation fault.
__strcat_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:666
666 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: No such file or direc
tory.
(gdb) bt
#0 __strcat_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:666
#1 0x00000000004006a3 in fun1 (s1=0x7fffffffebd8) at main.c:9
#2 0x00000000004006e4 in main () at main.c:17
(gdb)
I am confused because the string "Batman" is able to get printed inside fun1() , but its strcat is failing eventhough I am doing the same thing for both the cases.
Thanks in advance for any help.
When you do
str = "Batman";`
str no longer points to the malloc'ed memory. It point to the string literal "batman". So you are not allowed to concatenate the other string.
A way to see this is to add some simple printing - try:
char *str;
str = malloc(sizeof(char)*15);
printf("%p\n", (void*)str);
str = "Batman"; // str now points to a different location
printf("%p\n", (void*)str);
Use strcpy instead:
str = malloc(sizeof(char)*15);
strcpy(str, "Batman");
NOTICE: You assign too little memory for the concatenation of "Batman" and "&Superman". The first is 6 char, the second is 9 char so you need 6+9+1 = 16 char. The last +1 is for holding the string termination character, i.e. \0. So besides using strcpy, you also need to allocate 16 chars.
BTW:
You don't need to pass the address of str to the function as the function never do any assignments like *s1 = ... something... Just pass str
sizeof(char) is always 1 so you don't need to write it.
this was the code snippet asked for me in a interview and pls explain me what is the use of &.
#include<stdio.h>
int main()
{
char *str="INCLUDEHELP";
printf("%s",*&*str);
}
The &* is an empty operation. The &*str (or like &*&*&*&*&*&*&*&*&*str or any number of &*) is equivalent to just str. See C11 note102. We can omit it.
char *str="INCLUDEHELP";
printf("%s", *str);
This code with %s is invalid. The %s expects zero terminated char array. The *str is a char with the value of 'I', a character. The program on linux-like systems will most probably receive a segmentation fault signal, because 'I' will be an invalid address of a zero terminated character array.
If it were:
char *str="INCLUDEHELP";
printf("%c", *str);
or:
#include<stdio.h>
int main()
{
char *str="INCLUDEHELP";
printf("%c",*&*str);
}
, then the program would print a single character I on it's stdout.
The output is most probably the segfault.as it is the Undefined Behaviour. The &*... from the right mean. Dereference the pointer, get the address of the dereferenced char, and dereference this address again passing the char instead of the pointer to printf.
I executed the following code.
#include <stdio.h>
int main()
{char *a="awake";
printf("%s\n", *(a+1));
return 0; // expected out_put to be wake
}
You're dereferencing the pointer, which makes it a char but trying to output a string. Change your print statement to printf("%s\n", a+1);
*(a+1) is the same as a[1] which is a char, not the char * that printf expects for the %s.
EDIT: clarification: printf needs an address for the %s specifier, a+1 is such an address (namely the address of the second character in the string), but *(a+1) then gives the value at that address. Which is just a character and in all likelyhood not a valid memory location for printf to read.
You don't want to defrefeence the char *:
printf("%s\n", (a+1));
does what you want.
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.