The method signature for getenv
char *getenv(const char *name)
The return value is a pointer to char .
Now if we look at the below example :
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p;
p = getenv("PATH");
if(p != NULL)
printf("Current path is %s", p);
return 0;
}
The only confusion here is the "p" printed with format specifier "%s" as String but what about the Pointer Dereference
If I put "*p" instead, I end up with segmentation fault
while if I want to get the pointer address I can do this
printf("%p", p);
confusion about getting the value by deferencing the point "p" in our case.
Please explain
Looks like you're confused about some fundamental basics in C.
In case of
char *p;
p is a pointer to a series of char, which is in fact a \0 terminated
string. This string can be printed with printf("%s", p);
Since p is a pointer you can print the memory address it points to printf("%p", p);, which is exactly the same as if p was defined as void *p;
*p dereferences the first char in the string pointed to by p, which is essentially the same as p[0]. This string can be printed with printf("%c", *p); or printf("%c", p[0]);
Related
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void set(char* str){
str = malloc(10);
strcpy(str, "dog");
printf("\nstr = %s", str);
}
int main(){
char* s;
set(s);
printf("\n%s", s);
return 0;
}
Here's what I want to print out:
str = dog
dog
Here's what actuall gets printed out:
str = dog
(null)
Why is this? What I think I'm doing is passing an uninitalized pointer that then gets assigned a block of memory in set(), which then gets "dog" written into. What's actually going on?
There is no pass-by-reference in C. But pointers and indirection gives a facility to mimic that indirectly.
In your case, what is sent from main() to set() is the address in variable 's'. It
will have that value till malloc() statement executes. After that, str will have whatever address is returned by malloc().
When the same thing is expected in main, what should have been passed is the address
of 's' rather than what address it holds (like some of the examples above).
C is a pass-by-value language. There is no way to pass something by reference except explicitly. For your case that means expecting a pointer-to-a-pointer:
void set(char **str)
{
*str = malloc(10);
strcpy(*str, "dog");
printf("str = %s\n", *str);
}
And calling with the address of the pointer you want to 'fill in':
int main(void)
{
char *s;
set(&s);
printf("%s\n", s);
return 0;
}
Why isn't this function(char*) pass by ref?
C doesn’t have pass-by-reference. Everything is pass-by-value – it’s just that some values are also pointers to other values. Your uninitialized variable s is read when you call set(s) (which is undefined behaviour) in order to provide a value for its parameter str, then str = malloc(10) throws that value away to assign a new value to the local str.
You can pass a pointer to the pointer:
void set(char** str){
*str = malloc(10);
strcpy(*str, "dog");
printf("\nstr = %s", *str);
}
int main(){
char* s;
set(&s);
printf("\n%s", s);
return 0;
}
or return a pointer:
char* set(void) {
char* str = malloc(10);
strcpy(str, "dog");
printf("\nstr = %s", str);
return str;
}
int main(){
char* s = set();
printf("\n%s", s);
return 0;
}
You are passing an unasigned pointer to your set function, here a copy of the pointer is made and you use malloc on that copy. The original pointer in main is never updated with the new memory address.
To achieve what you want could be done this way:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void set(char** str){
*str = malloc(10);
strcpy(*str, "dog");
printf("\nstr = %s", *str);
}
int main(){
char* s;
set(&s);
printf("\n%s", s);
return 0;
}
I used a pointer to a pointer in set, and pass the memory address of the pointer s to it.
I am learning c, a beginner, can anybody please make me understood which concept am I missing?
And thanks in advance.
#include<stdio.h>
int main()
{
char s[10];
s[0]='A';
s[1]='B';
s[2]='\0';
char *p;
int i;
p=s;
printf("%c\n", *p); //It's ok.
printf("%s", *p); // or *s...what's wrong here,why does program crash?
return 0;
}
Change
printf("%s", *p);
to
printf("%s", p);
The reason why is that %s is expecting a pointer, and *p is the dereferenced value at p, aka the char value at p[0].
If this doesn't make sense, picture why printf("%c\n", *p) works. *p is the same as p[0], which is the same as s[0] since p points to s. Because s[0] is a char, %c works here because it is expecting a char. But %s on the other hand expects char *.
You want printf("%s", p). Don't dereference the pointer.
I want to display "string pointer affected" but I get an error. Here is my code:
#include<stdio.h>
main()
{
char* *p;
char * s="string pointer affected";
*p=s;
printf("%s",*p);
}
p doesn't point to any known location, so writing to *p is a bad idea.
You mean to say:
p = &s;
You dereference a pointer which is not initialized , which will cause undefined behaviour . This is problem -
*p=s;
You are using an uninitialized variable in the line below and in the printf statement. If you replace
*p = s;
with
p = &s;
then it will work.
Try:
#include<stdio.h>
main()
{
char *p; // <--------------------------
char *s="string pointer affected";
printf("===== s=%p\n", s);
p=s;
printf("===== p=%p\n", p);
printf("%s\n", p);
}
The problem with the original code is that p is uninitialized. So you cannot dereference it.
If you do want to use a pointer to a pointer, allocate the pointer first, and then take its address.
#include<stdio.h>
main()
{
char *q;
char **p = &q;
char *s="string pointer affected";
*p=s;
printf("%s\n", *p);
}
I have two pointers. A char pointer with the string "test", and a void pointer.
I'm trying to have pointer point to the address of string.
Here's my code:
#include <stdio.h>
int main(){
void *pointer = NULL;
char *string = "test";
*(char*)pointer = &string;
printf("The string address: %p\n", string);
printf("The string: %s\n", string);
printf("The pointer address: %p\n", pointer);
printf("The pointer points to: %p", *(char*)pointer);
return 0;
}
When I set pointer to be equal to the address of string on line 6 I get makes integer from pointer without a cast. How can I do this?
Edit:
I was printing the wrong addresses. I meant for the printf lines to look like this:
#include <stdio.h>
int main(){
void *pointer = NULL;
char *string = "test";
pointer = &string;
printf("The string address: %p\n", &string);
printf("The string: %s\n", string);
printf("The pointer address: %p\n", &pointer);
printf("The pointer points to: %p", pointer);
return 0;
}
It now properly prints out this:
The string address: 0028FF18 The string: test The pointer address:
0028FF1C The pointer points to: 0028FF18
So string and pointer are separate pointers and pointer points to string.
Why not simply do
#include <stdio.h>
int main(){
void *pointer = NULL;
char *string = "test";
pointer = &string; // point to the address of string
printf("The string address: %p\n", string);
printf("The string: %s\n", string);
printf("The pointer address: %p\n", pointer);
printf("The pointer points to: %p\n", (char*)(*(char**)(pointer)));
return 0;
}
If you want to point pointer at the string addressed by string,
pointer = string;
works.
If you want to point pointer at string,
pointer = &string;
is sufficient.
What you actually are doing is casting pointer to char*, and assigning through it, which is undefined behavior as pointer is NULL.
Actually, conversion from &string to char probably does not work either.
void *pointer = NULL;
pointer here is a pointer of type void. You need to first make sure that this pointer points to some valid memory location before dereferencing it.
Like
pointer = string;
PS: Here string is a string literal so it is read-only if you try to write to this memory location you might get segmentation fault.
If you want to have a pointer that points to the char pointer string, then you should do this:
pointer = &string
If you want to have a pointer that points to the string "test", then you should do this:
pointer = string
I am playing with array and pointer and got this segmentation fault. Can any one explain why I have been getting this segmentation fault in this code when I move my pointer "p" below "ptr" pointer in the code and when I comment out one of printf statement alternatively it disappears:
typedef struct str{
char* ptr;
}str_t;
copy(str_t t){
char a[12];
char *p; // <------ no error when move below ptr pointer
char *ptr;
printf("t= %s p = %d ptr = %d\n", t, p, ptr);
strcpy(a, t.ptr);
printf("a = %s %u\n", a, &a);
strcpy(ptr, t.ptr);
printf("ptr = %s %u\n", ptr, &ptr); //<--- comment it error disappears
p= t.ptr;
printf("p = %s %u",p, &p); //<--- comment it error disappears
}
int main ()
{
str_t t;
char app[] = "hello";
char ap[] ="world";
t.ptr = ap;
copy(t);
printf("%s\n", app);
return 0;
}
you can compile the code here to see the result :
http://codepad.org/Q7zS8NaC
Thank you , for visiting this question .
strcpy doesn't allocate space at the pointer, p, to store the string. You need to declare it as an array or allocate space with malloc or calloc.
Try this:
int len = strlen (t.ptr); // find length of string
char * ptr = calloc (len + 1, 1); // allocate space for ptr
if (!ptr) return; // error check calloc
strcpy (ptr, t.ptr); // copy the string
char * p = calloc (len + 1, 1); // do the same thing for p
if (!p) return;
strcpy (p, t.ptr);
That will fix your segmentation fault.
You have a couple of more errors though, which are mainly format issues.
%u prints an unsigned integer. It looks like you're trying to print a pointer, so use %p instead.
printf("t= %s p = %d ptr = %d\n", t, p, ptr); is totally wrong.
You need to reference the member of t, which is t.ptr
p is a pointer, not an integer. Use %p instead of %d
ptr is also a pointer. Use either %p or %s
Read the documentation of printf if you're ever unsure about formatting. In fact, read the documentation of any function, if you are unsure how to use it - you'll save yourself a lot of headaches.
Your code has several undefined behaviors:
The first printf prints a pointer using %d specifier
The second call of strcpy call attempts to write to memory pointed to by an uninitialized pointer
The second and third calls of printf passes a pointer to an array to a format specifier %u
Removing one of the pointers makes the code not crash, but since undefined behavior is there, the code does not work correctly, and may crash at any time.
Here is one way of fixing it:
char a[12];
char *p;
char *ptr;
printf("t= %s p = %x ptr = %x\n", t.ptr, (void*)p, (void*)ptr);
strcpy(a, t.ptr);
printf("a = %s %x\n", a, (void*)(&a[0]));
ptr = malloc(strlen(t.ptr)+1);
// In production, check ptr for NULL
strcpy(ptr, t.ptr);
printf("ptr = %s %x\n", ptr, (void*)&ptr);
p= t.ptr;
printf("p = %s %x", p, (void*)&p);
// Release the memory when you are done
free(ptr);