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
Related
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]);
This question already has answers here:
How to fix error Format specifies type 'char *' but the argument has type 'char'
(2 answers)
Closed 2 years ago.
Trying to understand pointer.
Below, I just want to prove to myself the below
address of str ( &str) = address of where str2 is pointed to(str2)
actual memory of address for str2 is something different(&str2)
However, when I compile below I get seg fault saying "morePointers.c:6:56: warning: format specifies type 'int' but the argument has type 'char *' [-Wformat]"
How can I correct this while proving this in the code?
int main(int argc, char** argv) {
char str = "goodbye";
char *str2 = str;
printf("%d %d %s %d %d\n", &str2, str2, str2, str, &str);
}
In this declaration
char str = "goodbye";
you are trying to initialize an object of the type char with a string literal that in the initialization expression has the type char *.
You have to write
char *str = "goodbye";
Instead of this declaration
char *str2 = str;
it seems you mean
char **str2 = &str;
that is you are creating a pointer that points to the pointer str.
Thus dereferencing the pointer str2 you will get the value stored in the pointer str that is the address of the first character of the string literal "goodbye".
Here is a demonstrative program
#include <stdio.h>
int main(void)
{
char *str = "goodbye";
char **str2 = &str;
printf( "str = %p is the same as *str2 = %p\n", ( void * )str, ( void * )*str2 );
printf( "str2 = %p contains the address of str (&str) = %p\n", ( void *)str2, ( void *)&str );
printf( "The string literal pointed to by str = %s\n"
"is the same as pointed to by *str2 = %s\n",
str, *str2 );
return 0;
}
The program output might look like
str = 0x561655562008 is the same as *str2 = 0x561655562008
str2 = 0x7ffdb7fc57a8 contains the address of str (&str) = 0x7ffdb7fc57a8
The string literal pointed to by str = goodbye
is the same as pointed to by *str2 = goodbye
Pay attention to that using the conversion specifier %d with pointers results in undefined behavior.
This would be the correct code:
#include <stdio.h>
int main(int argc, char** argv) {
char *str = "goodbye"; // a '*' was missing in your code
char* str2 = str;
// you need to use %p for pointer values
// and for each argument for a %p you need to cast to (void*)
printf("%p %p %s %p %p\n", (void*)&str2, (void*)str2, str2, (void*)str, (void*)&str);
}
Typical possible output for this code on a 32 bit system
00FFF710 00996B30 goodbye 00996B30 00FFF71C
Typical possible output for this code on a 64 bit system
0x7ffc8f58ada0 0x555ba93f6004 goodbye 0x555ba93f6004 0x7ffc8f58ad98
So I have this code in which allocation is happening in one function and deallocation is being done in the calling function. Getting Segmentation fault or Abort message while trying to free the memory either by ptr or *ptr. Kindly have a look:
#include <stdio.h>
int main()
{
char *ptr;
fun(&ptr);
printf("ptr = %p\n",ptr);
printf("&ptr = %p\n",&ptr);
printf("String ptr = %s\n",ptr);
free (ptr);
return 0;
}
void fun(char **str)
{
*str = malloc(10);
*str = "HELLO";
printf("str = %p\n",str);
printf("&str = %p\n",&str);
printf("String str = %s\n",*str);
}
Following is the output:
str = 0x7ffe63247858
&str = 0x7ffe63247838
String str = HELLO
ptr = 0x400764
&ptr = 0x7ffe63247858
String ptr = HELLO
*** Error in `/home/a.out': munmap_chunk(): invalid pointer: 0x0000000000400764 ***
Aborted
Question :
Why can't we free ptr ? And if we can, what is the best way to do it ?
you're overwriting the pointer value in the line after, making *str point to a literal.
So you have a memory leak and undefined behaviour by trying to free a literal.
You probably mean
strcpy(*str,"hello");
Note that those 2 lines could be changed into a working single line like this:
*str = strdup("HELLO");
which has the advantage of allocating the exact number of bytes for the string instead of guessing.
When you do *str = "HELLO"; it does not have the effect you expect. Instead of assigning value to the allocated memory, you are re-assigning the pointer to point to the string literal and thus later you try to deallocate it (thus the error). Instead of this you should use strcpy like strcpy(*str, "HELLO").
To answer the question of how to do this without explicit string copying, instead of
char *p = "hello";
do
char p[] = "hello";
The first points p to a non-modifiable portion of memory. The second allocates an array large enough to hold the literal and copies the literal into it.
you are changing memory address pointed str pointer after malloc in fun. you should do strcpy instead of direct assignment :
#include <stdio.h>
int main()
{
char *ptr;
fun(&ptr);
printf("ptr = %p\n",ptr);
printf("&ptr = %p\n",&ptr);
printf("String ptr = %s\n",ptr);
free (ptr);
return 0;
}
void fun(char **str)
{
*str = malloc(10);
strcpy(*str,"HELLO");//*str = "HELLO";
printf("str = %p\n",str);
printf("&str = %p\n",&str);
printf("String str = %s\n",*str);
}
I call a function global var as follow:
char *Pointer;
I then pass it into function:
char *MyChar = DoSomething (&Pointer);
which is defined as:
char *DoSomething (char *Destination)
{
free (*Destination);
//re-allocate memory
Destination = malloc (some number);
//then do something...
//finally
return Destination;
}
it only works if I use (*Destination) instead of (Destination). can someone tell me if that is correct? I still do not understand why it does not take (Destination).
It is correct, Destination is already declared as a pointer, so you pass the address of Destination in DoSomething(&Destination), that is like a pointer to pointer, then you need to dereference Destination inside DoSomething() function, for which the indirection operator * works.
But the right way, is not to pass the address of the pointer, but the pointer instead like in
DoSomething(Destination);
now, since you want to malloc Destination inside the function, you should the do this
char * DoSomething( char **Destination )
{
// free( Destination ); why?
//re-allocate memory
*Destination = malloc( some number );
//then do something...
//finally
return *Destination;
}
this is a demonstration of how you can use pointers
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char *copyString(const char *const source)
{
char *result;
int length;
length = strlen(source);
result = malloc(length + 1);
if (result == NULL)
return NULL;
strcpy(result, source);
printf("The address of result is : %p\n", result);
printf("The content of result is : %s\n", result);
printf("The first character of result is # %p\n", &result[0]);
return result;
}
int main()
{
char *string = copyString("This is an example");
printf("\n");
printf("The address of string is : %p\n", string);
printf("The content of string is : %s\n", string);
printf("The first character of string is # %p\n", &string[0]);
/* we used string for the previous demonstration, now we can free it */
free(string);
return 0;
}
if you execute the previous program, you will see that the pointers both point to the same memory, and the contents of the memory are the same, so calling free in main() will realease the memory.
Here is a correct approach
char *Pointer;
//,,, maybe allocating memory and assigning its address to Pointer
//... though it is not necessary because it is a global variable and
//... will be initialized by zero. So you may apply function free to the pointer.
char *MyChar = DoSomething( Pointer );
char * DoSomething( char *Destination )
{
free( Destination );
//re-allocate memory
Destination = malloc( some number );
//then do something...
//finally
return Destination;
}
As for your code then
Type of the argument does not correspond to type of the parameter in function call
char *MyChar = DoSomething (&Pointer);
the type of the parameter is char * ( char *Destination ) while the type of argument is
char ** ( &Pointer )
As Destination is a pointer then instead of
free (*Destination);
you have to write
free( Destination );
It's because you are passing in an address of the pointer char *Pointer with the line
char *MyChar = DoSomething (&Pointer);
Since you are passing in the address of the pointer in your function DoSomething it sees the functional scope variable Destination as a pointer to an address that is the address of the pointer Pointer.
So rather than passing in the address of Pointer with
char *MyChar = DoSomething(&Pointer);
you need to pass in the pointer itself like so:
char *MyChar = DoSomething(Pointer);
which will allow you to use
free(Destination);
Notice the lack of & indicating the address of Pointer.
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);