In the below code , why can't I dereference the array name ,since when an array is passed as an argument to a function , it becomes pointer to first element of the array , so why can't we dereference it then ?
#include <stdio.h>
int main(void) {
char s[] = "radha";
int a[2] = {0,1};
printf("%s ", *s);
printf("%d", *a);
return 0;
}
I am getting segmentation fault for the above code , what's the reason here , when I use a[0] ,it is internally converted as *(a+0) , so what's the issue in simply doing *a or *S ,please clarify .
printf("%s ",*s); expects second argument to be a pointer to string while you are passing char 'r' (dereferencing s gives you first array item as expected).
I have two suggestions of your,
Read the documentation.
The "%s" specifier expects a pointer of char, you are passing a char which is then considered an integer and dereference as if it were a pointer causing UNDEFINED BEHAVIOR.
If you read the documentation, and understand that char[] is converted to char * also that dereferencing a char * poitner will give you a char, then you would understand why this is wrong.
Enable compiler warnings. If you do so, then a warning telling you that you are passing the wrong type would save you a lot of time and let you learn more about how to invoke a given function.
If you ignored the warning, it's even worse. You should never ignore a warning unless you know beforehand that the compiler will complain about something. If the warning was not expected, then it's very likely an error instead.
Related
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.
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.
Situation
Consider the following source code which aims to print two a's, i.e. output should be "aa":
#include <stdio.h>
int main ()
{
char a = 'a';
void* a_pnt = &a;
void* b_pnt = (char*)a_pnt;
printf("%c", *(char*)a_pnt);
printf("%c", *b_pnt);// why is the compiler saying I am dereferencing a void pointer? It was already cast
return 0;
}
Complication
The printing of the first "a" works but the compiler is giving a compile time error on line 10 (second printing of "a") saying:
Invalid use of void expression
and a warning on the same line saying:
Dereferencing 'void *' pointer
Although b_pnt was indeed declared a void pointer, it was cast to a character pointer in its definition on line 7. My only guess as to why its complaining is something to do with the fact that I can only cast when referencing at the same time. My hunch is based off the fact that the first variable works just fine.
Solution
The solution is declare and define a character variable called 'b' and cast to character pointer upfront before printing it:
#include <stdio.h>
int main ()
{
char a = 'a';
void* a_pnt = &a;
void* b_pnt = a_pnt;
char b = *((char*)b_pnt);
printf("%c", *(char*)a_pnt);
printf("%c", b);// why is the compiler saying I am dereferencing a pointer?
return 0;
}
The question still remains: Why did the initial attempt fail?
I am deliberately starting off with void pointer to illustrate the issue. It could indeed have been avoided entirely ofcourse with the correct pointer type.
Just because you performed a cast when assigning to b_pnt doesn't mean that it's type changed. It's type is still void * and dereferencing it is an error.
You can freely assign any non-function pointer type to a void * without a warning. But the compiler doesn't keep track of what kind of pointer was stored there, so it's still a void * that needs to be casted before it can be dereferenced.
So I need to have a pointer to a value in a const char array. But I can't quite get it to work without errors. Here's the code.
int main (void)
{
const char *alp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *ptr = &alp[3];
printf("%s\n", ptr);
return 0;
}
Edit- Sorry for not mentioning the errors. The thing is I get tons of different errors depending on where I put different asterisks and ampersands. There is no one particular error. One of the more frequent ones I get says
"incompatible integer to pointer conversion assigning to 'char *'
from 'const char';"
In the end I just want "ptr" to be equal to a pointer pointing to "D" in the array "alp".
If you only want one character to print, change the %s to %c and dereference the pointer
printf("%c\n", *ptr);
It's true that you had a character pointer but %s tells printf to print from that pointer until it reads a null character. So we switch to %c which will print one character but it expects a value rather than a pointer to a value.
alp is a pointer to constant char.
ptr is a pointer to a non-const char.
If you want that to work out you would need to change ptr to be defined as:
char const * ptr = &alp[3];
The const is saying that you're not going to change it, but then you're trying to copy the reference to a variable without that limitation. Instead, try:
const char *ptr = &alp[3];
But note that as other posters have already suggested, this code will give you a pointer to a string beginning with the D (e.g. DEFGHI...), not just the character D.
#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"