Transferring values from void pointer - c

Can someone tell me whats wrong with this code?
base is a void pointer to a bunch of floats
i is a value >1
size is the size of the type (in this case float - 4 )
char *a = (char *)base;
char *temp = (char *)a + size * (i/2);
printf("%d: %d = ", i, temp);
memcpy(a + size * i , temp , size);
printf("%d\n", a + size * i);
This is the output:
2: 136724 = 136728
3: 136724 = 136732
4: 136728 = 136736
6: 136732 = 136744
7: 136732 = 136748
8: 136736 = 136752

If a was a void*, the compiler wouldn't allow you to write a + size*i (you can't do pointer arithmetic with incomplete types). Probably the type isn't what you think it is.
But why do you think there's a problem? The left-hand column advances half as fast as the right-hand column, and this is expected because you are dividing by 2.
You do realize that you're printing addresses, and not the values being copied, right?

char *a = (char *)base;
char *temp = (char *)a + size * (i/2);
printf("%d: %f = ", i, *(float *)temp);
memcpy(a + size * i , temp , size);
printf("%f\n", *(float *)(a + size * i));
The changes I have made are to dereference the pointers correctly (and casting them to the correct type) and to change %d to %f as you specified that base is an array of floats. %d is for ints and %f is for floats.
The reason your code did not work is that you were printing out the addresses and not the values.

Would you please tell us what you're trying to accomplish? Seems like a
homework problem, right?
The C language allows you to cast any pointer to a void*, and then cast it
back to the original pointer type, without losing any information. Anything
else you do with a void pointer is a bad idea, although some library functions
(such as memcpy) still have void* for historical reasons. That's also why
you don't need an explicit cast to go from any pointer type to a void*.
You cannot look at what the void* points to, until you cast it back to the
correct pointer type. And be careful when you do!
#include <stdio.h>
#include <memory.h>
/* It's a bad idea to pass Base as a void pointer,
but that's what you said you have. */
void silly_function(void*base, int i, int size) {
/* Using a char* that points to float, is an even worse idea!
char *a = (char *)base;
char *temp = (char *)a + size * (i/2);
printf("%d: %d = ", i, temp);
memcpy(a + size * i , temp , size);
printf("%d\n", a + size * i);
**/
/** Probably ought to have a big SWITCH statement here, based
on the data type. sizeof() isn't a good way to do this...
On many computers, sizeof(float)==sizeof(long), but that
doesn't mean that a float* is the same as a long* !!!
For now, I'm going to assume (as you did) that base points
to an array of float. */
/* I think you're trying to copy the first half of the array
into the second half of the array! But that's easy. */
float*firsthalf = (float*)base;
float*secondhalf = firsthalf + (i/2);
/* Show some starting values. */
printf("Before: %x --> %f, %x --> %f\n",
firsthalf, *firsthalf, secondhalf, *secondhalf);
/* Now do the copy */
memcpy(secondhalf, firsthalf, (i/2)*(sizeof(float)));
/* Now prove that it's been copied? */
printf("After: %x --> %f, %x --> %f\n",
firsthalf, *firsthalf, secondhalf, *secondhalf);
}
int main() {
/* This drives the test */
float ary[10] = {
1.1f, 2.2f, 3.3f, 4.4f, 5.5f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
silly_function(ary, 10, sizeof(ary[0]));
return 0;
}
On my system, the output is
Before: 12ff38 --> 1.100000, 12ff4c --> 0.000000
After: 12ff38 --> 1.100000, 12ff4c --> 1.100000
I hope this helps.

Related

How to allocate memory equal in size to a variable read from an input file?

I'm building a code to simulate the response of some dynamical systems for my PhD. Basically what I'm trying to do is:
Ask the user for the name of a input file that contains all parameters for the simulation;
Read the input file and assign each parameter to a specific variable in my program.
Do the calculations.
I'm having problems on step 2, as one of the values in the input file is the dimension dim of an dinamically allocated array *x.
Here is a working example of the code:
#include <stdio.h>
#include <stdlib.h>
void read_file(char *name, int *dim, double **x) {
// Open input file
FILE *input = fopen(name, "r");
if (input == NULL) {
// Return error
perror(name);
return;
}
// Read and assign system constants
fscanf(input, "%i", dim);
printf("dim = %i\n", *dim);
// Allocate memory for x[dim]
*x = malloc((*dim) * sizeof(*x));
double y[(*dim)];
printf("size of (*x) = %llu\n", sizeof(*x));
printf("size of y = %llu\n", sizeof(y));
// Security check for pointers
if(*x == NULL) {
free(*x);
printf("Memory allocation for *x did not complete successfully\n");
return;
}
// assign values to x[dim] vector
for (int i = 0; i < *dim; i++) {
fscanf(input, "%lf", &(*x)[i]);
printf("(*x)[%i] = %lf\n", i, (*x)[i]);
}
// Close input file
fclose(input);
}
char *get_input_filename(void) {
char *filename = malloc(200 * sizeof(*filename));
printf("Enter Input Filename: ");
scanf("%s", filename);
return filename;
}
int main (void) {
int DIM;
double *x = NULL;
char *input_filename = get_input_filename();
read_file(input_filename, &DIM, &x);
printf("size of (*x) = %llu\n", sizeof(*x));
for (int i = 0; i < DIM; i++) {
printf("(*x)[%i] = %lf\n", i, x[i]);
}
free(x); free(input_filename);
}
And here is the content of the input file in.txt for this example:
5
0.0 0.1 0.2 1.4 2.6
When I call *x = malloc((*dim) * sizeof(*x)); I expected to find the dimension of the system to be 5 * 8bytes, as the value for *dim is assigned in the previous line, however only 8 bytes are allocated. Then, I declared the y[(*dim)] variable to check if the sizeof a VLA would behave in the same way as the sizeof *x, just to compare. The sizeof(y) was what I expected, but the sizeof(*x) wasn't, as shown in the output:
Enter Input Filename: in.txt
dim = 5
size of (*x) = 8
size of y = 40
(*x)[0] = 0.000000
(*x)[1] = 0.100000
(*x)[2] = 0.200000
(*x)[3] = 1.400000
(*x)[4] = 2.600000
size of (*x) = 8
(*x)[0] = 0.000000
(*x)[1] = 0.100000
(*x)[2] = 0.200000
(*x)[3] = 1.400000
(*x)[4] = 2.600000
I understand that it cannot allocate memory if the value of *dim is unknown, but a value is assigned in the previous line.
Also, I even don't know how the program assigned values to (*x) successfully as it don't have the necessary allocation of bytes to do it.
What am I missing here? How can I allocate the memory correctly?
Thanks in advance
Both dim and x are output arguments; pointers that refer to locations where you're to store your results of this function (a size and a memory allocation sequence of double values).
This is where things are going off the rails:
*x = malloc((*dim) * sizeof(*x));
The left side is ok. And so is most of the right side. But if you're ever allocating to a pointer based on the size of the dereferenced data a pointer points to, you need to do so using just that: the size of the thing the pointer points to. x is a pointer-to-pointer, *x is a pointer, and the latter is the 'thing' we're allocating memory for, the address of which will be stored at *x.
Therefore, that should be:
*x = malloc((*dim) * sizeof **x);
Note: when I'm using variables as the operator argument for sizeof I personally strive not to use parens. It ensures I'm actually using a variable id rather than a type id, since the latter isn't allowed without parens. use what you favor at your discretion/whim.
More fundamental, however, your familiarity and understanding of sizeof is wrong and/or misled. You cannot acquire the size of dynamic-allocated memory region using sizeof. Using the sizeof operator on a pointer variable will give you exactly what you asked for: the size of the pointer variable (e.g. the size of a pointer). It is your responsibility to maintain and track magnitude of dynamic allocations (which, btw, your code does, using dim).

C fat pointer implementation failure

I have discovered a library recently which implements a C++ vector like functionality using fat pointers.
I have tried to replicate a similar behaviour in a short program (see the code below). I can access the array elements fine but when I try to get the number of elements my program prints garbage.
#include <stdio.h>
#include <stdlib.h>
int main()
{
double * a = NULL;
// the data
double b[] = {1, 2, 3, 5};
a = (int *) malloc(sizeof(int) + sizeof(double *));
a[0] = 4;
a++;
a = b;
// will print 1.0 2.0 3.0 5.0
printf("%lf %lf %lf %lf\n", a[0], a[1], a[2], a[3]);
// prints garbage
printf("%d\n", *((int *) a - 1));
// this will fail
free(((int *) a - 1))
return 0;
}
It is likely that the problem lies in the pointer arithmetic part of the code, i.e. (int *) a - 1 points to the wrong address, but I could not figure out why is that the case.
Any help is appreciated.
Packing the length at the beginning of the array is not a fat pointer, but an ill-formed PASCAL array.
int main(fat_pointer);
int main(int argc, char* argv[argc]); // standard signature for main is a fat pointer
A fat pointer is a pointer and an index. The data type of the index is an integral type which guarantees that sizeof index <= sizeof(size_t). In other words, sizeof(int) <= sizeof(size_t) is a mandate for all compliant hosted environment because main demands so. Note that size_t is not defined for freestanding environment.
The problem with _s functions is that they use sal.h from Microsoft which allow the usage of variables before declaration.
char * strcpy_s(char * restrict dest, rsize_t destsz, char const * restrict src);
// fat pointer form fails
char * strcpy_s(char dest[destsz], rsize_t destsz, char const * src);
The fat pointer form fails because destsz is declared afterwards, so it cannot be used. Annex K is horrible because it has usage before declaration in fat pointer form. Look at main where argc is declared before argv; that is the proper way to declare a fat pointer.
#include<stdio.h>
#include<stdlib.h>
void print_vector_double(int len, double d[len])
{
for (int i = 0; i < len; i++)
printf("%lf ", d[i]);
printf("\n");
printf("%d\n", len);
}
int main(int argc, char* argv[argc])
{
// C89 VLA - initialized VLA
double b[] = { 1, 2, 3, 5, };
int b_len = (int)(sizeof b / sizeof b[0]);
print_vector_double(b_len, b);
// C99 VLA - uninitialized VLA
int c_len = b_len;
double c[c_len];
c = b;
print_vector_double(c_len, c);
// Good Old Heap for Dynamic Arrays
int a_len = b_len;
double * a = malloc(a_len * sizeof * a);
double * temp = memcpy(a, b_len * sizeof * b, b);
if (temp != a) exit(EXIT_FAILURE);
print_vector_double(a_len, a);
free(a), a = NULL, a_len = 0;
}
A fat pointer is what you pass to a function. If you are not passing anything to another function, there is no fat pointer.
Cello failed to understand what a fat pointer really is.

How to Calculate the Element Addresses of an N-Dimensional Array

From what I understand, blocks of allocated memory is continuous, so addresses in an array are sequential in multiples of the size of the array data (int = 4 on some systems, etc.)
I've also seen that for an array A and index i, A[i] == *(A+i) in C.
A 2D array is like an array of arrays, so I wanted to know how to determine the expression for an N-dimensional array if I was crazy enough not to use the [] operator.
If the array was created with pointers, wouldn't it be necessary to know the length of the level?
For
int array2d[X][Y];
the two expressions are equivalent:
array[1][2];
*((int *)array + 1*Y + 2);
For
int array3d[X][Y][Z]
the two expressions are equivalent:
array[1][2][3];
*((int *)arr + 1*Y*Z + 2*Z + 3);
So, for
int arraynd[X][Y][Z]..[N]
the two expression are equivalent:
arraynd[1][2][3]...[n];
((int *)array + 1*X*Y*Z*...*N + 2*Y*Z*...*N + 3*Z*...*N + ... + n);
Suppose you declare int a[m][n]; If you reference a[i][j], it is equivalent to (a[i])[j] which, as you noted, is equivalent to (*(a+i))[j], which is equivalent to *((*(a+i))+j). In terms of bytes, the integer is scaled by the size of the object pointed to, so i is scaled by the size of a[0], or *a, which is the size of the sub-array, which is sizeof(int) * n. The dereference of the result, via the * operator, is essentially a type cast, converting it from a pointer to the sub-array, type int (*)[n], to a pointer to an element of the sub-array, type int *. Then, when adding j, it is scaled by sizeof(int). The outer dereference, via the * operator, actually dereferences the pointer, either reading the value or modifying it, depending on the context.
Edit: Here's a simple demonstration program you can try. It illustrates what I explained:
#include <stdio.h>
int main()
{
int a[5][10];
printf("%d %d %d\n", sizeof(int[5][10]), sizeof(int[10]), sizeof(int));
printf("%d %d %d\n", sizeof(a), sizeof(a[0]), sizeof(a[0][0]));
printf("%d %d %d\n", sizeof(a), sizeof(*a), sizeof(**a));
void *p1 = a;
void *p2 = a + 1;
void *p3 = *(a + 1) + 3;
printf("%d %d\n", (int) (p2 - p1), (int) (p3 - p2));
printf("%d %d\n", 1 * (sizeof(int) * 10), 3 * sizeof(int));
return 0;
}

error: invalid operands to binary * Pointer to a pointer to a matrix

I am getting error: invalid operands to binary * on lines 13, 20, 25, 31, and 36. I'm not sure how to deal with dynamic memory allocation to a pointer to a pointer to a matrix. Also, how to store integers in a matrix like fashion with this pointer to a pointer. Also, I realize there are lots easier ways of going about this in terms of the pointers, but I have to not use any brackets and the functions inputs were supplied to me.
void read_matrices(int **A, int **B, int **C, int *m, int *n, int *p, char *file) {
FILE *fp = fopen(file, "r");
if (!fp) {
fprintf(stderr, "\n Error: file open failed for file '%s'\n\n", file);
exit(0);
}
/* read & output m, n, p */
fscanf(fp, "%d\n%d\n%d\n", m, n, p);
printf("\n m: %d\n n: %d\n p: %d\n\n", *m, *n, *p);
/* allocate memory for A and set values to null */
A = calloc(m * n, sizeof(int));
/* read A */
int i, j;
for (i = 0; i < *m; i++) {
fscanf(fp, "\n");
for (j = 0; j < *n; j++) {
fscanf(fp, "%d", *(A + i * n + j));
}
}
/* allocate memory for B and set values null */
B = calloc(n * p, sizeof(int));
/* read B */
for (i = 0; i < *n; i++) {
fscanf(fp, "\n");
for (j = 0; j < *p; j++) {
fscanf(fp, "%d", *(B + i * p + j));
}
}
/* allocate memory for C and set values null */
C = calloc(m * p, sizeof(int));
/* close FP & free allocated memory */
fclose(fp);
}
It's a bit hard to understand what you are doing in that function, but it seems you just need to better understand pointers in C.
For this line:
A = calloc(m * n, sizeof(int));
What this is doing is it is trying to multiply two pointers, but I'm assuming you want to multiply the values they point to, so you need to prefix m and n with a * to de-reference them (and get their value).
For the assignment to A, what you are trying to do right now, is assign a pointer to a "pointer to a pointer", which is impossible. You need to deference A by prefixing it with a * to get the pointer that it is pointing to, and then you also should be casting the result of calloc to (int*) to match what you are assigning to.
Example:
*A = (int*)calloc(*m * *n, sizeof(int));
The same rules apply to the other errors in the code.
Let's look at your first error. The variables involved are declared as int *m, int *n, so pointers to ints.
On line 13:
A = calloc(m * n, sizeof(int));
The error is due to m * n. You're saying multiply pointer m with pointer n. That makes no sense. What you probably mean is to multiply the values pointed to by those pointers: (*m) * (*n).
Those to be honest, I don't see why you made m and n pointers in the first place.
Also, A is declared as a pointer to a pointer. That probably means you also want *A.
I'd recommend you read up on pass-by-value vs. pass-by-address.

Saving double values in char[] buffer

I try to write program whitch uses stack for present some kind of data (char, double or string).
char *data_buffer;
double n;
...
data_buffer = (char*)malloc(4096 * sizeof(char));
...
*(data_buffer + buffer_top) = n; //buffer_top - just offset for first byte
...
printf("%f ", (double)*(data_buffer + buffer_top));
Variables data_buffer and buffer_top correct.
But output is strange. It correct only if n < 127.
Why could it be?
P.S. I don't want to change type of data_buffer becase it includes also char and string of different lengths.
Example of work (!! - test output of n before write it to buffer:
126 //push
!! 1.260000e+02
127 // push
!! 1.270000e+02
128 // push
!! 1.280000e+02
. // pop
-128.000000 //error
. //pop
127.000000 //ok
. //pop
126.000000 //ok
123456 // push
!! 1.234560e+05
. //pop
64.000000 //error
Both lines are missing a cast to (double *), so they do a char assignment and a read, respectively. Here's what your code is actually doing with some explicit (char) casts added to highlight the incorrect type conversions.
*(data_buffer + buffer_top) = (char) n;
...
printf("%f ", (double) (char) *(data_buffer + buffer_top));
What you want is:
*((double *) (data_buffer + buffer_top)) = n;
...
printf("%f ", *((double *) (data_buffer + buffer_top)));

Resources