assign address of char pointer to int - arrays

I have a function that gets an integer as a parameter. I want to send a char array's address to it, then print the array from its address. I mean:
void printSomeThing(int x){
printf("Variable is: %s\n", /*What to type here?*/);
//I want this printf to write "file.txt"
}
....
int main(){
char filename[10] = "file.txt";
char *filePointer = filename; //So it points to filename[0]'s address.
int x = /*How to convert the address of the pointer (or the char array) to an integer?*/
printSomeThing(x);
}
So, I want to send the char array's address to the function and print that address's value.
NOTE: I can't change the printSomeThing parameter. It has to be an int.

The proper way to convert between pointer addresses and integers is to use the uintptr_t integer type. This is a type guaranteed to be large enough to hold an address (unlike int). This code is fairly safe and portable:
#include <stdio.h>
void printSomeThing(uintptr_t x){
printf("Variable is: %s\n", (char*)x);
}
int main(){
char filename[10] = "file.txt";
char *filePointer = filename; //So it points to filename[0]'s address.
uintptr_t x = (uintptr_t)filePointer;
printSomeThing(x);
}

If sizeof(int) != sizeof(char*), then what you're trying to do is not possible, in general.
However, there is a way to still make this work. Before I tell you how to achieve this, let me reiterate what others have said: you should not use an int as a pointer. This is not a good idea. What I am going to demonstrate is just that: a demonstration. Just because it can be done doesn't mean it should be done.
One way to make this work is to map memory at an address smaller than 1 << (sizeof(int) * 8). Then, copy the string you want to that memory location. Now, you can pass this pointer to your printSomething(int) function.
There is one problem with this solution: it's not portable, so it doesn't always work. I couldn't get it to work with clang on macOS, but it does work here. Here is the code I used.
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
void printSomething(int x){
printf("Variable is: %s\n", (char*) x);
}
int main(){
char filename[10] = "file.txt";
char *allocd = mmap((void*) 0x10000, sizeof(filename)+1,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
strcpy(allocd, filename);
printSomething((int) allocd);
}
Another solution that should probably only be used as a demonstration is one where you ask gcc to define a section at a low memory address. This answer does something along those lines. This is probably not portable either.

The best way I could think to do this given that you dont want to just pass a pointer to the array - would be to cast it to an unsigned long in order to give it to the function.
However your compiler might complain that you are passing an integer value to a string pattern in printf but that is by virtue of the design you are using.
If you dont need to use printSomeThing(int i) then just pass the char* itself or use a void* if you need other things passed through and use some sort of flag to tell the function what type you passed

Related

Can we print the data just by using bare address in C?

I was wondering whether we can print data at a particular location just by using the bare address of that location in C language.
for eg, Here is the code I used :
#include<stdio.h>
int main(int argc, char** argv) {
int num = 10;
int *ptr;
ptr = &num;
//To output the address of the "num" variable
printf("Address: %p\n", ptr);
//Address is 0x7fff47808f50...
//Using that address to print the data at variable "num"
printf("Data: %d\n", *(0x7fff47808f50));
return 0;
}
But it is showing error. Maybe I've used the wrong syntax or maybe this is not the way to do it.Anyhow, please tell me the right way to do it.
You could (thought shouldn't) cast the integer to a pointer like so: (void *) 0x7fff47808f50.
The conversion has implementation-defined and undefined aspects, however, meaning your mileage will vary. The value will obviously change from compiler to compiler, perhaps even for different compilations, and byte order probably won't be the same as the way we conventionally write numbers, meaning you'll probably have to tinker quite a bit to get this working.
This is nonetheless demonstrable in practice, when that implementation-defined behaviour allows us to reproduce that behaviour, the following will be compliant:
unsigned long long ptr_as_integer = (unsigned long long) "hello world";
printf("%s", (void *) ptr_as_integer);
int value = 42;
unsigned long long value_ptr_as_integer = (unsigned long long) &value;
printf("%d", * (int *) value_ptr_as_integer);
There's also the uintptr_t type, which is designed specifically for this, but that's optional and so not guaranteed to exist...
It's fine to be curious; that's how we learn best... but please don't use this in practice! How often have you been taught not to use magic numbers?
You can use a char * to alias a pointer of another type to read individual bytes:
int i;
char *p = (char *)ptr;
for (i=0; i<sizeof(*ptr); i++) {
printf("p[%d]=%02hhx", i, p[i]);
}
Modify your code
#include<stdio.h>
int main(int argc, char** argv) {
int num = 10;
int *ptr;
ptr = &num;
//To output the address of the "num" variable
printf("Address: %p\n", ptr);
//Address is 0x7fff47808f50...
//Using that address to print the data at variable "num"
printf("Data: %d\n", *ptr);
return 0;
}
the answer to you question is YES.
BUT:
You must be 100% sure what address to use. For example in any kind of firmware you always have addresses of registers defined in manuals as regular numbers. and we use them like this
#define MY_REG_ADDR 0x12345ABC
int a = *((int*)(MY_REG_ADDR))
Modern OSes do address randomization so executable's virtual address sapce is changed every time you run your application so you CANNOT just use hardcoded address.
here is the output after i ran the app 4 times (modified code)
Address: 0x7ffc279af5ac
Data: 10
Address: 0x7ffc2d78021c
Data: 10
Address: 0x7fffb36ae32c
Data: 10
Address: 0x7ffca2c2a9ec
Data: 10
Every tine you change your code memory layout might change so variabl's address might also change

c - memcpy and pointers. Still work. Why?

EDIT:
What should I do to have a correct code then ?
EDIT2:
Ok, I correct the code below
Context
Fiddling with memcpy.
Linux, 64 bits.
gcc 4.8.x
Code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void d(char ** restrict a, char ** restrict b){
char r[20];
memcpy(r,*a, strlen(*a)+1);
// it is the same thing as before since *c is equivalent to &r (or put simply r).
char *restrict c = malloc(20);
memcpy(c,*a, strlen(*a)+1);
// that one bugs me. why b alone and not *b ??
// EDIT : this is incorrect
memcpy(b,*a, strlen(*a)+1);
// EDIT : this is correct
memcpy(*b,*a, strlen(*a)+1);
printf("pointer c -> hey %s\n",c);
printf("array r -> hey %s\n",r);
// EDIT : this is incorrect
printf("double pointer -> hey %s\n",b);
// EDIT : this is correct
printf("double pointer -> hey %s\n",*b);
}
int main(void)
{
char a[] = "YOU";
char * b = a;
char * c = malloc(20);
d(&b, &c);
return 0;
}
Question
I would like to undertsand why memcpy doesn't complain about me passing double pointer to it, while it needs a pointer only.
I know that with chars *b == &a == a and that an array is referenced by its first member up to '\0'. The problem really is with passing a double pointer to memcpy.
why didn't I have to do
memcpy(*b, *a, strlen(*a)+1);
since memcpy signature is
void * memcpy ( void * destination, const void * source, size_t num );
and first argument is a "Pointer to the destination array where the content is to be copied, type-casted to a pointer of type void*", according to cplusplus.com.
What is the "catch" here please ?
Thanks a lot
Well, a double pointer is a single pointer to single pointer, so it can be passed to a function that expects a void pointer.
It is of course another thing whether or not your code is correct... It's not and works only by coincidence. Note that not only you use memcpy() to write to a wrong location, but you also print the same wrong location of memory as a string in your printf(). The "coincidence" here is that both of these "wrong" locations are the same, so you falsely assumed that it works fine.
Try to really print the right thing and you'll see the mayhem:
printf("double pointer -> hey %s\n",*b);
Consider what would happen if you wanted to copy the representation of a pointer to another one, like this:
char *p;
char *q = NULL;
memcpy(&p, &q, sizeof q);
should the compiler really complain in this case? Nope.
The point is that void * is untyped. It can point to any object type. It's not a constraint that a void * can't point to a pointer-to-pointer. It absolutely can.
As to why it "works": It does not work. It only appears to be working. Because of the invalid pointer operation, the code has undefined behavior, so it can do anything. In the better case, it crashes and makes the problem apparent. In your case, the error remained silent and the program was pretending it worked.

How do I correctly use a void pointer in C?

Can someone explain why I do not get the value of the variable, but its memory instead?
I need to use void* to point to "unsigned short" values.
As I understand void pointers, their size is unknown and their type is unknown.
Once initialize them however, they are known, right?
Why does my printf statement print the wrong value?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void func(int a, void *res){
res = &a;
printf("res = %d\n", *(int*)res);
int b;
b = * (int *) res;
printf("b =%d\n", b);
}
int main (int argc, char* argv[])
{
//trial 1
int a = 30;
void *res = (int *)a;
func(a, res);
printf("result = %d\n", (int)res);
//trial 2
unsigned short i = 90;
res = &i;
func(i, res);
printf("result = %d\n", (unsigned short)res);
return 0;
}
The output I get:
res = 30
b =30
result = 30
res = 90
b =90
result = 44974
One thing to keep in mind: C does not guarantee that int will be big enough to hold a pointer (including void*). That cast is not a portable thing/good idea. Use %p to printf a pointer.
Likewise, you're doing a "bad cast" here: void* res = (int*) a is telling the compiler: "I am sure that the value of a is a valid int*, so you should treat it as such." Unless you actually know for a fact that there is an int stored at memory address 30, this is wrong.
Fortunately, you immediately overwrite res with the address of the other a. (You have two vars named a and two named res, the ones in main and the ones in func. The ones in func are copies of the value of the one in main, when you call it there.) Generally speaking, overwriting the value of a parameter to a function is "bad form," but it is technically legal. Personally, I recommend declaring all of your functions' parameters as const 99% of the time (e.g. void func (const int a, const void* res))
Then, you cast res to an unsigned short. I don't think anybody's still running on a 16-bit address-space CPU (well, your Apple II, maybe), so that will definitely corrupt the value of res by truncating it.
In general, in C, typecasts are dangerous. You're overruling the compiler's type system, and saying: "look here, Mr Compiler, I'm the programmer, and I know better than you what I have here. So, you just be quiet and make this happen." Casting from a pointer to a non-pointer type is almost universally wrong. Casting between pointer types is more often wrong than not.
I'd suggest checking out some of the "Related" links down this page to find a good overview of how C types an pointers work, in general. Sometimes it takes reading over a few to really get a grasp on how this stuff goes together.
(unsigned short)res
is a cast on a pointer, res is a memory address, by casting it to an unsigned short, you get the address value as an unsigned short instead of hexadecimal value, to be sure that you are going to get a correct value you can print
*(unsigned short*)res
The first cast (unsigned short*)res makes a cast on void* pointer to a pointer on unsigned short. You can then extract the value inside the memory address res is pointing to by dereferencing it using the *
If you have a void pointer ptr that you know points to an int, in order to access to that int write:
int i = *(int*)ptr;
That is, first cast it to a pointer-to-int with cast operator (int*) and then dereference it to get the pointed-to value.
You are casting the pointer directly to a value type, and although the compiler will happily do it, that's not probably what you want.
A void pointer is used in C as a kind of generic pointer. A void pointer variable can be used to contain the address of any variable type. The problem with a void pointer is once you have assigned an address to the pointer, the information about the type of variable is no longer available for the compiler to check against.
In general, void pointers should be avoided since the type of the variable whose address is in the void pointer is no longer available to the compiler. On the other hand, there are cases where a void pointer is very handy. However it is up to the programmer to know the type of variable whose address is in the void pointer variable and to use it properly.
Much of older C source has C style casts between type pointers and void pointers. This is not necessary with modern compilers and should be avoided.
The size of a void pointer variable is known. What is not known is the size of the variable whose pointer is in the void pointer variable. For instance here are some source examples.
// create several different kinds of variables
int iValue;
char aszString[6];
float fValue;
int *pIvalue = &iValue;
void *pVoid = 0;
int iSize = sizeof(*pIvalue); // get size of what int pointer points to, an int
int vSize = sizeof(*pVoid); // compile error, size of what void pointer points to is unknown
int vSizeVar = sizeof(pVoid); // compiles fine size of void pointer is known
pVoid = &iValue; // put the address of iValue into the void pointer variable
pVoid = &aszString[0]; // put the address of char string into the void pointer variable
pVoid = &fValue; // put the address of float into the void pointer variable
pIvalue = &fValue; // compiler error, address of float into int pointer not allowed
One way that void pointers have been used is by having several different types of structs which are provided as an argument for a function, typically some kind of a dispatching function. Since the interface for the function allows for different pointer types, a void pointer must be used in the argument list. Then the type of variable pointed to is determined by either an additional argument or inspecting the variable pointed to. An example of that type of use of a function would be something like the following. In this case we include an indicator as to the type of the struct in the first member of the various permutations of the struct. As long as all structs that are used with this function have as their first member an int indicating the type of struct, this will work.
struct struct_1 {
int iClass; // struct type indicator. must always be first member of struct
int iValue;
};
struct struct_2 {
int iClass; // struct type indicator. must always be first member of struct
float fValue;
};
void func2 (void *pStruct)
{
struct struct_1 *pStruct_1 = pStruct;
struct struct_2 *pStruct_2 = pStruct;
switch (pStruct_1->iClass) // this works because a struct is a kind of template or pattern for a memory location
{
case 1:
// do things with pStruct_1
break;
case 2:
// do things with pStruct_2
break;
default:
break;
}
}
void xfunc (void)
{
struct struct_1 myStruct_1 = {1, 37};
struct struct_2 myStruct_2 = {2, 755.37f};
func2 (&myStruct_1);
func2 (&myStruct_2);
}
Something like the above has a number of software design problems with the coupling and cohesion so unless you have good reasons for using this approach, it is better to rethink your design. However the C programming language allows you to do this.
There are some cases where the void pointer is necessary. For instance the malloc() function which allocates memory returns a void pointer containing the address of the area that has been allocated (or NULL if the allocation failed). The void pointer in this case allows for a single malloc() function that can return the address of memory for any type of variable. The following shows use of malloc() with various variable types.
void yfunc (void)
{
int *pIvalue = malloc(sizeof(int));
char *paszStr = malloc(sizeof(char)*32);
struct struct_1 *pStruct_1 = malloc (sizeof(*pStruct_1));
struct struct_2 *pStruct_2Array = malloc (sizeof(*pStruct_2Array)*21);
pStruct_1->iClass = 1; pStruct_1->iValue = 23;
func2(pStruct_1); // pStruct_1 is already a pointer so address of is not used
{
int i;
for (i = 0; i < 21; i++) {
pStruct_2Array[i].iClass = 2;
pStruct_2Array[i].fValue = 123.33f;
func2 (&pStruct_2Array[i]); // address of particular array element. could also use func2 (pStruct_2Array + i)
}
}
free(pStruct_1);
free(pStruct_2Array); // free the entire array which was allocated with single malloc()
free(pIvalue);
free(paszStr);
}
If what you want to do is pass the variable a by name and use it, try something like:
void func(int* src)
{
printf( "%d\n", *src );
}
If you get a void* from a library function, and you know its actual type, you should immediately store it in a variable of the right type:
int *ap = calloc( 1, sizeof(int) );
There are a few situations in which you must receive a parameter by reference as a void* and then cast it. The one I’ve run into most often in the real world is a thread procedure. So, you might write something like:
#include <stddef.h>
#include <stdio.h>
#include <pthread.h>
void* thread_proc( void* arg )
{
const int a = *(int*)arg;
/** Alternatively, with no explicit casts:
* const int* const p = arg;
* const int a = *p;
*/
printf( "Daughter thread: %d\n", a );
fflush(stdout); /* If more than one thread outputs, should be atomic. */
return NULL;
}
int main(void)
{
int a = 1;
const pthread_t tid = pthread_create( thread_proc, &a );
pthread_join(tid, NULL);
return EXIT_SUCCESS;
}
If you want to live dangerously, you could pass a uintptr_t value cast to void* and cast it back, but beware of trap representations.
printf("result = %d\n", (int)res); is printing the value of res (a pointer) as a number.
Remember that a pointer is an address in memory, so this will print some random looking 32bit number.
If you wanted to print the value stored at that address then you need (int)*res - although the (int) is unnecessary.
edit: if you want to print the value (ie address) of a pointer then you should use %p it's essentially the same but formats it better and understands if the size of an int and a poitner are different on your platform
void *res = (int *)a;
a is a int but not a ptr, maybe it should be:
void *res = &a;
The size of a void pointer is known; it's the size of an address, so the same size as any other pointer. You are freely converting between an integer and a pointer, and that's dangerous. If you mean to take the address of the variable a, you need to convert its address to a void * with (void *)&a.

C Double Pointer to Structure

I am trying to work out a double pointer to a structure in C and cannot figure out what is going wrong... The simple source is below:
typedef struct
{
int member;
} mystruct;
void myfunc(mystruct **data)
{
(*data)->member = 1;
}
void main(int argc, char *argv[])
{
mystruct **data;
myfunc(data);
printf("member = %d\n", (*data)->member);
}
A similar question was asked here: How to work with pointer to pointer to structure in C? on how to modify a member of a structure through a double pointer. The solution was the syntax (*data)->member = 1; which makes sense. But in my little application here, I receive a seg fault when executing that line. What am I doing wrong?
Thanks
You need to point to something if you are going to dereference a pointer. Try this:
void main(int argc, char *argv)
{
mystruct actualThing;
mystruct *pointer = &actualThing;
mystruct **data = &pointer;
myfunc(data);
printf("Member: %d", (*data)->member);
}
You received a segfault because you did not allocate a struct.
The value of data is garbage, so it is pointing to some place in memory that is not owned by your process, or is otherwise inaccessible.
You need to first allocate an object of type mystruct. Here is a working example for you: http://ideone.com/XIdJ8
data is not initialized, and hence doesn't point to any sensible memory address. Moreover, there is no mystruct structure floating around, so there really isn't even any sensible data to point to. For your example, you want to:
Create a mystruct.
Make a pointer to it.
Make a pointer to that pointer.
If you only need to pass the double pointer to a library function, you don't need to create a variable for it. You make a normal pointer variable, initialize it to point to appropriate storage (if required by the function), then pass the address of the pointer (thus creating the double-pointer "on the fly").
I've never used libusb, so I'll give an example using a standard library function. From the manpage:
#include <stdlib.h>
long int strtol(const char *nptr, char **endptr, int base);
It only looks like a double-pointer. It's really a simulated-pass-by-reference single pointer. Allowing the function to return extra information besides its normal return value. strtol returns a long integer but it also can tell you at what point the string contents stopped looking like a number.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *str = "99RED BALLOONS";
char *what;
long num;
num = strtol(str, &what, 10);
printf("Quantity: %ld; Description: %s;\n", num, what);
return 0;
}
Output:
Quantity: 99; Description: RED BALLOONS;
Or maybe you can try this:
void main(int argc, char*argv[])
{
mystruct *data;
myfunc(&data);
printf("member = %d\n", data->member);
}
This works for me in C++ and not needed to point another variable.
You're passing it a pointer, but the pointer isn't pointing at anything.
This may be more useful:
void main(int argc, char *argv[])
{
mystruct data;
mystruct *ptr = &data;
myfunc(&ptr);
printf("member = %d\n", (*ptr)->member);
}

Learning C - Pointers and memory addressing

I am learning C programming and I have a simple question about pointers...
I used the following code to play around with pointers:
#include <stdio.h>
int main (int argc, const char * argv[]) {
int * c;
printf("%x\n",c);
return 0;
}
When I print the value of C, I get back a 0. However, when I print &c (i.e. printf("&x\n",&c) I get an address in memory...
Shouldn't I be getting an address in memory when printing the pointer (i.e. printf("%x\n",c)?
--- EDIT ---
#include <stdio.h>
#include <stdlib.h>
int main (int argc, const char * argv[]) {
char * a = malloc(11);
printf("String please\n");
scanf("%s",a);
printf("%s",a);
}
The question is, why does printf("%s",a) returns the string instead of the address that is stored in a?
Shouldn't I use *a to follow the pointer and then print the string?
your current program is not correct. You define variable and do not set value before first use. the initial value is not guranteed for c, but you are lucky and it is equal to 0. It means that c points to nowhere. when you print &c you print address of variable c itself. So actually both versions print address.
printf is actually quite a complex function and can be made to do all sorts of tricks by giving it the right format specifier.
In your string example:
printf("%s", a)
the "%s" tells the printf function that the following variable should be treated as a string. In C, a string is a pointer to one or more char, terminated by a char containing 0. This is a pretty common request, which is why printf supports a format specifier "%s" that triggers this relatively complex behavior. If you want to print the address contained in the string pointer you have to use the format you found earlier:
printf("%x\n",a);
which tells printf to treat the contents of a as an unsigned integer, and print it in base 16.
*a would just be the value pointed to by a, which is just a single character.
You could print the single character with
printf("%c", *a);
Having int* c; If you print value of c, you get back a value that should be interpreted as a memory address of an integer value. In you example it might be 0 or something completely different as you are not initializing c.
If you print &c you get memory address of the pointer c (stored in stack).
#include <stdio.h>
int main (int argc, const char * argv[]) {
int * c;
int a=10;
c = &a;
printf("%x\n",c);
return 0;
}
This may clarify what happens when you make the int pointer point to something in memory.

Resources