segmentation fault in C assign string to char - c

#include <stdio.h>
#include <stdlib.h>
int main()
{
char a="9jhjhi";
printf("%s",a);
}
Why does this throw a segmentation fault? What happens behind the screens?

You need to use char *a = "...".
printf when passed %s will run through a string looking for a 0/NULL byte. In your case you are not assigning a string literal to a, and in fact your compiler should have thrown a warning that you were trying to initialize a char from a pointer.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *a="9jhjhi";
printf("%s",a);
}

Your error is that
char a="9jhjhi";
should be
char *a="9jhjhi";
What happens is undefined behavior - so anything could happen.
Your assigning a string literal to a char, so your a will contain a pointer(to the beginning of that string) converted to a char - whatever that'll be.
%s conversion in printf assumes you pass it a string, which must be a char* pointing to a sequence of chars ending with a 0 terminator. You passed it a char, which certainly does not meet those requirements, so it's quite undefined what'll happen - a crash could be common.
You should also return something from the main() method - it's declared to return an int after all.

a is initialized to a (cast to integer and truncated because char is 3 or 7 bytes too small) pointer that points to a char array (propably somewhere in ROM). What follows is undefined, but it's propably like this: When you pass it to printf with a %s in the format string, it takes the value of a (something in 0-255) and 3 (or 7) unrelated bytes from the stack, gets some bogus address and wreaks havok by accessing someone else's memory.
Use char *a = ....

C does not have strings as in String b = new String();
C has arrays of type char.
So char a="123123" should be a character array.
You aren't using anything from stdlib.h in that code either so there is no reason to #include it.
Edit: yeah, what nos said too. An array name is a pointer.

You mean
char *a = "9jhjhi";
If this compiles without warnings, your compiler settings are messed up. The warnings from gcc show plainly what's happening:
test.c: In function ‘main’:
test.c:5: warning: initialization makes integer from pointer without a cast
test.c:6: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
The string literal is interpreted as a pointer, which is converted (and truncated) to a char.
Then the char is sent into printf as a number, but interpreted as a string. Since it's not null-terminated in any way, printf probably overruns memory when racing through that "string".

When you declare char a without a pointer symbol, you are only allocating enough space on the stack for a single character.
Strings in C are represented by a char array, or a pointer to a char array, terminated by the null character '\0'. But if you use a literal string, the compiler takes care of all of that for you.
Here's how you can get your code to work, then:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *a = "9jhjhi";
printf("%s",a);
}

First of all, you're trying to save an entire string into a single char variable. Use char array (char[size]) instead. You may also want to terminate the string with "\0".

You could remove this error in two ways.
1.char * p="karthik A"
2.char [ ]p="karthik A"

Related

Why we didn't use * during dereferencing the pointer?

In the below code, we get a pointer from strdup(source) and we store it in a pointer named target.
Now, when we print the string using pointer, we don't add * at the beginning of the pointer: why is it so? As I studied whenever we want to dereference any pointer we use *pointer_name. If we add * in the below code, we get an error.
I am very beginner, so pls ans in easy words.
#include<stdio.h>
#include<string.h>
int main()
{
char source[] = "Programming";
char* target = strdup(source);
printf("%s\n",target);
return 0;
}
printf expects a char pointer in the place of the %s specifier.
https://en.cppreference.com/w/c/io/fprintf
char* target = strdup(source);
printf("%s\n",target);
Why we don't use *target in the code above?
The explanation is quite simple, as already stated in previous answers: target has type char pointer, which is exactly what printf() wants in the above call.
Now, printf() is a little complicated because its semantic is not simple - basically it accepts zero or more arguments after the first, of any type (possibly applying promotion). But if we use strdup() again, maybe it is simpler:
char* target2 = strdup(target);
Here, if you wrote strdup(*target), the compiler might warn that you are passing a char instead of a pointer to char.
strdup() returns a char*, hence the char* type of target. target holds a pointer to the first character in an array of chars. printf("%s", string) expects string to be a char*, so there’s no reason to do anything to target; just pass it to printf().
If you dereferenced target, you would get a single char (P in this case). printf() would then complain that you had supplied a character instead of a string (pointer to character). Even worse, the program could compile, and then printf() would try to print the string at address P (0x50), which would result in probably unwanted behaviour.
When working with arrays—a string is a type of array—you rarely want to dereference the array.

Dereferencing char pointer returns int ? why? [duplicate]

This question already has answers here:
Char pointers and the printf function
(6 answers)
Closed 1 year ago.
For example, the following code returns an error and a warning when compiled and an int when changed to %d
Warning:
format %s expects argument of type char *, but argument 2 has type int
void stringd() {
char *s = "Hello";
printf("derefernced s is %s", *s);
}
*s is an expression of type char since it's the dereference operator applied to a pointer-to-char1. As a result, it gets promoted to an int when passed to printf; in order to print a null-terminated string, you need to pass the pointer to the first character (i.e. just s).
1 even though s is not a const pointer, you should not try to modify the characters it points to as they may be placed in read-only memory where string literals are stored on some architectures/environments; see this discussion for more details.
The variable s is a pointer to the first out of a series of characters which are consecutive in memory (colloquially referred to as a "string", though it's not quite the same). It's a pointer to a character, thus char *.
Dereferencing s (by doing *s) gives you the first of those characters, h, whose type is now just char. One layer of indirection was stripped away.
Thus, the issue is that you're trying to pass a character (char), where a string (char *) was expected. char * was expected because you used the %s type character in your format string to printf. Instead, you should use %c, which expects single, simple char.
The mistake here is actually quite grave. If you were allowed to pass this 'h' where a char * was expected, you would end up with the ASCII code of 'h' (0x68) being passed where a pointer was expected. printf would be none-the-wiser, and would try to dereference that value, treating 0x68 like a pointer to the beginning of a string. Of course, that's probably not a valid memory location in your program, so that should seg-fault pretty reliability, if it were allowed to happen.

why printf doesn't accept a pointer as an argument

why codeblocks crashes when I try to run this code :
#include <stdio.h>
#include <stdlib.h>
void main(void)
{
char *ch= "Sam smith";
printf("%s\n",*ch);
}
but it works fine when I remove *ch in printf and replace it with just ch like this
void main(void)
{
char *ch= "Sam smith";
printf("%s\n",ch);
}
shouldn't *ch mean the content of the address pointed to by ch which is the string itself, and ch mean the adress of the first element in the string? so i expected the opposite!
I use Code blocks 17.12, gcc version 5.1.0, on windows 8.1 .
*ch dereferences the pointer to yield the data it points to. Here the first character of the string.
Providing the wrong specifier to printf is undefined behaviour (passing a value where printf expects a pointer)
printf("%c\n",*c);
would print the first character, without crashing. If you want to print all the string using %c (or use putchar), loop on the characters. But that's what %s does.
As a side note, better use const to reference literal strings so no risk to attempt to modify them:
const char *ch= "Sam smith";
why codeblocks crashes when I try to run this code :
char *ch= "Sam smith";
printf("%s\n",*ch);
ch is of type char *.
The %s conversion specifier expects a char *.
You pass *ch, which is the dereferenced ch, i.e. of type char.
If conversion specifiers do not match the types of the arguments, bad things (undefined behavior) happens.
shouldn't *ch mean the content of the address pointed to by ch which is the string itself
There is no data type "string" in C, and thus no "pointer to string".
A "string", in C parlance, is an array of characters, or a pointer to an array of characters, with a null-byte terminator.
ch is a char *, a pointer to the first character of that array - a string, so to speak.
*ch is a char, the first character of that array.
In C, You do not dereference a pointer to a string, when you want to use the whole string the pointer points to. This dereferencing process would result in the first character of the respective string, which is not what you want.
Furthermore, it is undefined behavior if a conversion specifier does not match to the type of the relative argument.
Thus,
printf("%s\n",*ch);
is wrong. *ch is the first character in the string, in this case S, of type char but the %s conversion specifier expects an argument of type *char.
printf("%s\n",ch);
is correct. ch is of type *char as required by the conversion specifier %s.
So, Codeblocks "crashes" apparently because of the mismatching argument type.

Segmentation fault by passing arguments to a function (C, codeblocks on linux)

Why do i keep getting "segmentation fault (core dumped)" by running this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
printf("%d", strlen(argc));
return 0;
}
That's my "argc"
gnome-terminal --disable-factory -t Es1 -x /usr/bin/cb_console_runner LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. /.../Lab1/Es1/bin/Debug/Es1 Es1.cbp es1file.txt es1out.txt (in /.../Lab1/Es1/.)
size_t strlen(const char *str)
The strlen() function takes a pointer to character string. and you are passing an integer to it.
That's because argc isn't a string, it's an integer value. The name argc stands for "argument count", and tells you the number of entries in the argv array.
Using argc as a pointer to a string leads to undefined behavior, which often results in crashes. Really, using anything that is not a pointer to a string as argument to a function which expects a pointer to a string will lead to undefined behavior.
Don't you get a warning about it? Then you need to enable more warnings when compiling! You should get a warning telling you that you are "making a pointer from integer without cast" (or something similar).
argc is an integer, but strlen() expects a pointer to a string (char *), that's why you get a Segmentation Fault.
1°) strlen, as its name clearly states, gives you the length of a string. Here, you're trying to use it on a int : argc. (Which gives you the length of the argument array argv).
In C, strings are arrays of characters terminated by the "\0" character. Strlen will only work safely if you use on such an array (if the array do not have a "\0" ending character, you'll get the same error).
2°) If you want to display the number of arguments, simply use argc (as in "argument count") minus one (since the name of the program will be the first argument).
3°) If you want to display the length of one argument, you'll need to specify the argument and then use strlen. E.g. :
if (argc > 1) {
printf("%d", strlen(argv[1]));
}

Why is the character d printed when I assign a string literal to a char variable?

#include<stdio.h>
int main(void) {
char a = "any"; //any string
printf("%c", a);
getch();
}
Why always d (for %c) or 100 (for %d) gets printed? What's happening?
char a="any"; is not declaring any string. Your compiler should through error/warning. You need
const char *a = "any";
Now
printf("%c", *a);
will print character a as pointer a is pointer to the first element of the string literal any.
Your code has issues. On
char a="any";
the string literal "any" is a pointer but you are saving it in a (small) integer type. Because the value of a is (part of) an address it will have an essentially arbitrary value. On my machine it prints "T" (if I remove the getch() line because that doesn't compile).
GCC gives the following warning:
warning: initialization makes integer from pointer without a cast
and whatever compiler you are using probably tells you something similar. You should really take this warning seriously.
"something between double quotes"
Allocates memory for the string and returns a pointer to the string in memory. you need to store this pointer in a using char *a = "abc"; now 'a' is a pointer to the string abc.
printf("%s",a) this will print the entire string abc.
for a single character use single quotes 'a' in this case char a = 'b'; is correct.
printf("%c",a) this will print b.
printf("%d",a) this will print the ascii value of 'b', which is 98
In the statement
char a = "any";
the string literal "any" evaluates to the address of its first character which is of type const char *. Assigning a const char * to a char variable implicitly converts the pointer to an integer. This emits the following warning if you compile with -W gcc flag:
warning: initialization makes integer from pointer without a cast [enabled by default]
What happens next is the least significant byte of the cast integer value is assigned to the char variable a. This is a random value and cannot be predicted. On my machine, it happened to be the ascii code for the character /. On your machine, it happened to be 100, the ascii code for the character d. It is just pure chance. Nothing else.
You should assign a string literal to a const char * as:
const char *a = "any";
and print the string pointed to by a by the %s conversion specifier as:
printf("%s\n", a);
Also note that getch is not a C standard library function, so your program won't compile on a linux machine. You can use getchar for the same effect, though.

Resources