Dereferencing a void pointer using its size in C [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I know that we cannot dereference a void pointer until and unless we typecast it.
void *ptr = call_a_function();
printf("%d",*(int *)ptr);
This informs the datatype of element(in this case its integer) to the compiler so that it can dereference the amount of space required for it(in this case its 4 bytes).
Suppose I dont know the final datatype, however I know the size of datatype. Can I still dereference it using only the size(4 bytes) and not the datatype(not using int)??
In other words is there a way to tell the compiler how many bytes of memory to read by providing the number of bytes to extract and not the datatype??
EDIT -
I needed to swap the contents of two void * pointers.
Got influenced by the regular way of swapping two values i.e storing the value of one pointer in a temporary variable and then proceed with swapping.
Was trying to attempt the same thing without knowing the datatype but only its size( since the function with this swap code accepts size of variable as one parameter ). However after reading the answers and comments, got to realize that I really dont need to dereference it. Probably memcpy is the correct way to go.

Suppose I dont know the final datatype, however I know the size of datatype. Can I still dereference it using only the size(4 bytes) and not the datatype(not using int)??
Since you cannot deduce or assume the data type, you can't dereference the pointer once to get the complete object. However, you can extract each byte and use it anyway you want.
void *ptr = call_a_function();
unsigned char* cptr = (unsigned char*)ptr;
for (int i = 0; i < num_bytes; ++i )
{
unsigned char c = cptr[i];
// Use c
}

In this case, the whole is not the sum of its parts. Casting not only provides the compiler with the size of the data but also how that data is to be interpreted. Suppose you get 4 bytes, this could be a string of three characters with a NULL byte or a signed integer, which could be encoded in big-endian or little-endian depending on the platform. So knowing the size is not sufficient to properly handle the data even if you could tell the compiler how many bytes to read/dereference.

Related

Segmentation Fault by trying to access binary file [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
My program stores matrix in binary files, when I try to "load" them during the same use of the program, everything works well.
However, when I close the program and use it later, it's impossible to access to the same files and I get a Segmentation fault (core dumped) error.
Here's the function that "loads" the matrixes :
void Loading(int mat**){
char* name = malloc(sizeof(char)*20);
printf("Enter name of the file");
scanf("%s",name);
FILE* file=fopen(name,"rb");
if (file==NULL){
printf("error opening file");
exit(0);
}
fread(mat,sizeof(int)*M*M,1,file);
fclose(fichier);
}
where M is a constant.
Again it works perfectly when I store/load mutliple times during the same use of the program
sorry for the mistakes I am not an english speaker
As presented, the question is missing key elements to allow a full analysis, nor a complete answer. But with what is shown, here are some suggestions:
1) The reason(s) for your segmentation fault cannot be identified with absolute certainty because some of the pieces are missing from your post. However, given the fact that it works sometimes, and not others, suggests undefined behavior is playing a part. If I were to guess at the source of undefined behavior, it would be that you are passing around a double pointer variable int **mat, when only a single pointer variable int *mat is necessary (see prototype of fread() below.), further leading me to believe that memory for mat has not been correctly created. I suggest changing:
void Loading(int mat**) // double pointer is not needed here
to
void Loading(unsigned int mat*) //and memory allocation method adjusted accordingly.
(See reason for unsigned in 3) below.)
2) The prototype for the function fread() is:
size_t fread (void *Buffer, size_t Element_Size, size_t Number_of_Elements, FILE *Stream);
In your call:
fread(mat,sizeof(int)*M*M,1,file);
Arguments 2 & 3 appear to be reversed. It should probably be written:
fread(mat, sizeof(unsigned int), M*M, file);
3) Why unsigned int verses int when working with binary data?:
Your post is not explicit on how the data is written to the file, or exactly what format it is in, but generally, when working with binary data, it is better to stick with unsigned types for the reasons listed here.
You have a pointer to your buffer for matrix int **mat.
The problem is, that this doesn't point to single continuous place in memory.
int mat** is a pointer to array of pointers to int. This is a place in memory that should contain more pointers one stored after another. Each of them (int*) then should point into different arrays, that would finally contain array of integers.
Basically you use command fread to write whole data into the array of pointers. Maybe you don't have enough space to store your data at all. Even if you would, you need another kind of pointer.
If you have one continuous array, you could point to it using int *. Then you would pick some element by calculating an index.
int *mtx = (int*) malloc(M*M*sizeof(int);
int x = 2, y = 3;
int index = y*M+x;
mtx[index] = 123; // write to matrix coordinates 2,3
You could use fread with this kind of buffer with no problem, just check how are matrix elements indexed in your input file, maybe the x,y is swapped.

can anyone explain the meaning of this peace of code from c [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
the code is from C the code is written below:-
int main(){
char* time = (char *)malloc(10240 * sizeof(char));
scanf("%s",time);
return 0;
}
Error:
Because there is no prototype in scope for malloc the compiler interprets the result (of type void*) as type int.
Then it converts that value to type char* and assigns the resulting (meaningless) value to time.
Then, still using the meaningless value, it attempts to store there a value read and interpreted as an integer from standard input.
It then exits without doing anything more. Particularly it doesn't use the value read or release the memory (probably) allocated earlier.
it has first reserved memory dynamically from the heap by using malloc function, then it is scanning a string. pay attention to the format fo %s conversion specifier: the argument related to it is a pointer.(not for example time[0].)
don't forget that the memory should be free after the work is done
syntax: free (time);
char* time = (char *)malloc(10240 * sizeof(char));
Here, you use malloc() to allocate 10240 * sizeof(char) blocks of memory for you. sizeof(char) is equal to 4 bytes, so you are allocated 10240 * 4 = 40960 blocks of memory as int by default, as you have not specified any prototype in scope (seen as void*) for malloc()
You then cast the memory space to a char * and have *time point the first block in that memory allocated to you.
scanf("%s",time);
In this line, you try to store a value read as integer input from scanf() in time. Your format specifier is wrong here.
The program then terminates, without freeing the memory you allotted in it, and without doing anything with the inout you took with scanf().

How to resolve a variable for char length? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
EDIT
i want to create a program which will work with a long number. the user will be asked to input the length (in digits) of the number they want to work with. there is a
char aa [the chosen length goes here];
where in the [] brackets should be the value that was input by the user.
it could look like this:
"please input the length in digits"
there is a scanf and you input, for example, 17
then a char aa [17] is created
i just don't know how can i use a variable to input a value in the [] brackets defining the memory size that is saved for a char
You want a variable lenght array, you can do it like this:
int digit;
scanf("%d", &digit);
char test [digit+1];
This will work for your purposes. Usual restrictions of course apply.
Keep in mind this functionality was only added in the C99 Standard. So if your compiler supports only previous standards, this will not work.
However, the more appropriate and better practice method to use is to use malloc to allocate the char array properly
int digit;
scanf("%d", &digit);
char* aa = malloc(digit + 1);
//Do what you want with the char array aa
free(aa);
Do not forget to check the result of malloc() against NULL and free the variable afterwards to prevent memory leaks if you want to do this.
Also be aware that the "array" malloc returns is actually just a pointer, which is very relevant when trying to determine the size/length of it, using sizeof:
char real_array[5];
sizeof(real_array); // == 5
char* dynamic_array = malloc(5);
sizeof(dynamic_array) // == sizeof(char*) == on most systems = 8
What you are asking is variable length array which is possible in C99. See Dynamic array allocation on stack in C
Look at the following code snippet:
int size;
scanf("%d", &size);
char array[size + 1]; //1 extra space to accommodate `\0` character
printf("%d\n", sizeof(array));
This will print sizeof(char) * (size+1) proving the array creation dynamically.
The only disadvantage of this way over malloc way is after declaring an array (which is of user-input size) you can't change the array size in program. It's fixed.
While using dynamic memory allocation (malloc, calloc) you can change the array size whenever possible in a program by freeing the memory.
Since variable length array is possible in c99 you may have to use gcc --std=c99 -c program.c to compile your source code. For other compiler refer the proper compiler manual.

why we use sizeof using malloc? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
What is purpose of using sizeof using malloc in C?
Why its necessary?
I mean we can use sizeof but we already know the size(=1000 bytes) what we are allocating in memory?
I am beginner in C so. This might be a very obvious question.
DataTypes And Memory Matter
The answer is in the data types. While you know how many objects you want to allocate memory for, you may not want to go through the trouble of mentally computing their size.
So Does Maintainability
Also, what if the composition of these changes later? Then you're screwed and have to edit everything.
So that's irrelevant in your example, without context. But in the case where you want to allocate memory for more complex things (say, a struct with a number of fields), it does become quite important and useful.
Example 1 (not so important here):
char *s = malloc(100 * sizeof(char));
But hey, it's just chars, it's fine, you could have done that:
char *s = malloc(100);
Generally works. But shooting yourself in the foot, as you'll see below.
Example 2 (matters a bit already):
int *i = malloc(100 * sizeof(int));
Sure, you could have written that:
int *i = malloc(100 * 4);
That is, assuming you develop for just one architecture you know pretty well.
Example 3 (starting to matter quite a bit!):
typedef struct s_listelement{
int dataitem;
struct s_listelement *link;
} t_listelement;
t_listement *le = malloc(sizeof(t_listelement));
Now imagine that linked-list item's structure contains a bunch of other fields...
Would you want to trust sizeof(), or go have fun and do the math yourself?
Suppose you want to allocate memory for storing ints. Your initial guess will be, okay I need to have n integers and each integer requires x bytes. So space will be n*x bytes.
But actually this x depends on architecture. It maybe 16 bit, 32 bit, etc. So to make your code able to work in different environments, it is recommended to use n*sizeof(int) instead of n*x.
For example, if you need to allocate space for 10 integers:
int *p=malloc(sizeof(int)*10);
What happens if you change the size of mallocated?
You will have to 1) calculate again the new size (letting aside multiple target architectures problems, where you will have to calculate the new size in each target), 2) search for all malloc(1000), make sure it refers to mallocated (which might be not obvious) and replace with new size.
You don't have any of these 2 problems using sizeof. Thus using sizeof leads to a more maintainable and readable code.

Reference a Register in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
This is from the perspective of someone on a Linux x86 system. Is it possible to store something other than a hardcoded address in a pointer? Here's the catch though: the value going to be stored in the pointer will have previously been stored as a string. Pretty sure there isn't a way for me to reference any register or other pointer but I just wanted to be sure. And I know people are going to ask why I want to do something like this; it would take too long to explain and I'm absolutely sure there is no alternative solution.
Sould have added this:
char* addresses = "\x32\x45\x19..."
I want to store something other than a hardcoded address in the "addresses".
EDIT:
lol wow I thought I was fairly clear. I have a array of characters, a pointer, or as I call it: a string. This string is going to be treated as a ZVAL struct in PHP. I am wondering if I can store information other than hardcoded addresses within the string.
If the address is stored as a string, you can convert the string to an address (probably via uintptr_t defined in <stdint.h> or <inttypes.h>). You take the bytes in the string and shift and mask them to produce the integer value equivalent to the address, and then assign the address to the pointer.
char *addresses = "\x32...";
char *string = addresses;
uintptr_t value = 0;
for (i = 0; i < sizeof(value); i++)
value = (value << 8) | (*addresses++ & 0xFF); // Sign extension avoided
void *memory_location = (void *)value;
I'm assuming the first byte in the string is the MSB of the address; if (given that you're on Intel) this is wrong (LSB is stored first), you have to adapt the loop to reverse the ordering — one of those infamous 'Exercise for the Reader' observations.
Or you play fast and loose and make the chip do the work. On RISC platforms (non-Intel), this would lead to a SIGBUS error in general; you might get lucky some of the time, though.
char *addresses = "\x32...";
void *memory_location = (void *)(*(uintptr_t *)addresses);
This tells the code to treat the char * as if it were a uintptr_t *, dereference it (reading the whole string at once, except if the address is not properly aligned, it will be two fetches, maybe with a kernel trap in the middle), and assign the value to the memory location.
If your code has any pretense at portability, make sure this is in the 'non-portable code' section.
This is a technical solution to the problem posed (as I understand it); it is not a recommendation that you use it.
you said "lol wow I thought I was fairly clear. I have a array of characters, a pointer, or as I call it: a string. This string is going to be treated as a ZVAL struct in PHP. I am wondering if I can store information other than hardcoded addresses within the string."
Not in the way you do it.
char * addresses = "\x32\x45\x19..." ;
addresses is set to point to something you should not change.
you need to allocate storage for that stuff.
e.g.
char stuff [256] ;
char * addresses = stuff;
memcpy(stuff,"\x32\x45\x19...",sizeof("\x32\x45\x19..."));

Resources