Invalid conversion 'void*' to 'struct*' [duplicate] - c

This question already has answers here:
malloc - invalid conversion from void* to double*
(2 answers)
Closed 4 years ago.
I'm beginner in C. I'm trying to practice with solving some problems. And I'm getting this error when I compile my code.
[Error] invalid conversion from 'void*' to 'triangle*' [-fpermissive]
The code and purpose is explained below.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct triangle
{
int a;
int b;
int c;
};
typedef struct triangle triangle;
//sort_by_area() function is here
int main()
{
int n;
scanf("%d", &n);
triangle *tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
return 0;
}
As you can see I have structure and I tried to allocate memory for it with the quantity of input. And try to use it for sort_by_area function. But the problem is triangle *tr = malloc(n * sizeof(triangle)); line gives me the error mentioned above.
Also this code is working for online compilers. I tried to run this code on DEV C++ with default settings. I don't know about the versions and changing the versions of my compiler. I don't even know whether it is about the compiler version. But I am wondering why I'm getting this error. What is the logic behind.

This looks like C code, but you're compiling with a C++ compiler. As such, it complains on the line you mentioned because malloc returns a void * but you're assigning the result to a triangle *.
In C++ an explicit cast is required for this. In C, a void * may be implicitly converted to or from any object pointer type.
Since this appears to be C code and not C++ code, you should compile with a C compiler.

You compile this program as C++ program and this implicit conversion is not allowed in C++.
As I know dev C++ uses MinGW and you may use -xc option to compile program as C program or Settings -> language standard -> and choose the language standard needed

The code looks like C code but you are compiling it with C++ compiler.
Make sure that the file has proper extension for C++(not .c extension).
malloc() returns a (void *) pointer by default, so you have to explicitly cast the (void *) to (triangle *) in your code.
But if you are writing C++ code then I would recommend not to use malloc and free, instead try to use "new" operator in C++ since while instantiating objects it will call the constructors as well(unlike in malloc).
So to avoid complications go with new and delete in C++.
The code in C should look like (file a.c)
Compile using: gcc a.c -o a.o
Run using : ./a.o
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct triangle {
int a;
int b;
int c;
};
typedef struct triangle triangle;
int main() {
int n;
scanf("%d", &n);
triangle *tr = (triangle *)malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
//sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
free(tr);
return 0;
}
The same code in C++ would look like (file a.cpp)
Compile using: g++ a.cpp -o a.o
Run using : ./a.o
#include <iostream>
using namespace std;
struct triangle {
int a;
int b;
int c;
};
int main() {
int n;
cin >> n;
triangle *tr = new triangle[n];
for (int i = 0; i < n; i++) {
cin >> tr[i].a >> tr[i].b >> tr[i].c;
}
// sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
cout << tr[i].a << " " << tr[i].b << " " << tr[i].c << "\n";
}
delete [] tr;
return 0;
}

triangle *tr = (triangle*)malloc(n * sizeof(triangle));
Change the line as shown above. malloc returns generic pointer, so you need to explicitly typecast it to your desired pointer.
Refer this

Related

With openmp in C, how can I parallelize a for loop that contains a nested comparison function for qsort?

I want to parallelize a for loop which contains a nested comparison function for qsort:
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
int main(){
int i;
#pragma omp parallel for
for(i = 0; i < 100; i++){
int *index= (int *) malloc(sizeof(int)*10);
double *tmp_array = (double*) malloc(sizeof(double)*10);
int j;
for(j=0; j<10; j++){
tmp_array[j] = rand();
index[j] = j;
}
// QuickSort the index array based on tmp_array:
int simcmp(const void *a, const void *b){
int ia = *(int *)a;
int ib = *(int *)b;
if ((tmp_array[ia] - tmp_array[ib]) > 1e-12){
return -1;
}else{
return 1;
}
}
qsort(index, 10, sizeof(*index), simcmp);
free(index);
free(tmp_array);
}
return 0;
}
When I try to compile this, I get the error:
internal compiler error: in get_expr_operands, at tree-ssa-operands.c:881
}
As far as I can tell, this error is due to the nested comparison function. Is there a way to make openmp work with this nested comparison function? If not, is there a good way to achieve a similar result without a nested comparison function?
Edit:
I'm using GNU C compiler where nested functions are permitted. The code compiles and runs fine without the pragma statement. I can't define simcmp outside of the for loop because tmp_array would then have to be a global variable, which would mess up the multi-threading. However, if somebody has a suggestion to achieve the same result without a nested function, that would be most welcome.
I realize this has been self answered, but here are some standard C and OpenMP options. The qsort_r function is a good classic choice, but it's worth noting that qsort_s is part of the c11 standard, and thus is portable wherever c11 is offered (which does not include Windows, they don't quite offer c99 yet).
As to doing it in OpenMP without the nested comparison function, still using original qsort, there are two ways that come to mind. First is to use the classic global variable in combination with OpenMP threadprivate:
static int *index = NULL;
static double *tmp_array = NULL;
#pragma omp threadprivate(index, tmp_array)
int simcmp(const void *a, const void *b){
int ia = *(int *)a;
int ib = *(int *)b;
double aa = ((double *)tmp_array)[ia];
double bb = ((double *)tmp_array)[ib];
if ((aa - bb) > 1e-12){
return -1;
}else{
return 1;
}
}
int main(){
int i;
#pragma omp parallel for
for(i = 0; i < 100; i++){
index= (int *) malloc(sizeof(int)*10);
tmp_array = (double*) malloc(sizeof(double)*10);
int j;
for(j=0; j<10; j++){
tmp_array[j] = rand();
index[j] = j;
}
// QuickSort the index array based on tmp_array:
qsort_r(index, 10, sizeof(*index), simcmp, tmp_array);
free(index);
free(tmp_array);
}
return 0;
}
The version above causes every thread in the parallel region to use a private copy of the global variables index and tmp_array, which takes care of the issue. This is probably the most portable version you can write in standard C and OpenMP, with the only likely incompatible platforms being those that do not implement thread local memory (some microcontrollers, etc.).
If you want to avoid the global variable and still have portability and use OpenMP, then I would recommend using C++11 and the std::sort algorithm with a lambda:
std::sort(index, index+10, [=](const int& a, const int& b){
if ((tmp_array[a] - tmp_array[b]) > 1e-12){
return -1;
}else{
return 1;
}
});
I solved my problem with qsort_r, which allows you to pass an additional pointer to the comparison function.
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
int simcmp(const void *a, const void *b, void *tmp_array){
int ia = *(int *)a;
int ib = *(int *)b;
double aa = ((double *)tmp_array)[ia];
double bb = ((double *)tmp_array)[ib];
if ((aa - bb) > 1e-12){
return -1;
}else{
return 1;
}
}
int main(){
int i;
#pragma omp parallel for
for(i = 0; i < 100; i++){
int *index= (int *) malloc(sizeof(int)*10);
double *tmp_array = (double*) malloc(sizeof(double)*10);
int j;
for(j=0; j<10; j++){
tmp_array[j] = rand();
index[j] = j;
}
// QuickSort the index array based on tmp_array:
qsort_r(index, 10, sizeof(*index), simcmp, tmp_array);
free(index);
free(tmp_array);
}
return 0;
}
This compiles and runs with no issue. However, it is not completely ideal as qsort_r is platform and compiler dependent. There is a portable version of qsort_r here where the author summarizes my problem nicely:
If you want to qsort() an array with a comparison operator that takes
parameters you need to use global variables to pass those parameters
(not possible when writing multithreaded code), or use qsort_r/qsort_s
which are not portable (there are separate GNU/BSD/Windows versions
and they all take different arguments).

2-dimensional array in a struct in C

I'm trying to initialize a 2-dimensional array in a structure but I always get an error :
gcc -g -Wall -W -I/usr/include/SDL -c -o fractal.o fractal.c
In file included from fractal.c:2:0:
fractal.h:12:12: error: array type has incomplete element type ‘double[]’
double values[][];
Here's the code:
struct fractal {
char name[64];
int height;
int width;
double a;
double b;
double meanValue;
double values[][]; /*This line is causing the error*/
};
Ideally I'd like to initialize the height and width of the 2-dimensional array like this:
struct fractal {
/*... Same code as above ...*/
double values[width][height];
};
But then I get two other errors when compiling:
gcc -g -Wall -W -I/usr/include/SDL -c -o fractal.o fractal.c
In file included from fractal.c:2:0:
fractal.h:12:19: error: ‘width’ undeclared here (not in a function)
double values[width][height];
^
fractal.h:12:26: error: ‘height’ undeclared here (not in a function)
double values[width][height];
^
I've looked about everywhere but my code should work and I can't figure out why it doesn't.
Thanks for the help
As a disclaimer, this is something of an advanced topic, so if you are a beginner you might want to just back away from it entirely and just use a double* array followed by a call to malloc for each pointer. (Fine for beginners, unacceptable in professional code.)
It is an advanced topic since this particular case is a weakness in C. The feature you are trying to use, with an empty array at the end of a struct, is known as flexible array member. This only works for one dimension however. If both dimensions are unknown at compile time, you have to come up with a work-around.
The allocation part is as for any flexible array member: allocate the struct dynamically and make size for the trailing array.
fractal_t* f = malloc(sizeof *f + sizeof(double[height][width]) );
(In this case taking advantage of the convenient VLA syntax, although a flexible array member is not a VLA.)
Technically, the last member of the struct is supposedly double[] now, or so says the struct declaration. But memory returned by malloc has no actual effective type until you access it, after which the effective type of that memory becomes the type used for the access.
We can use this rule to access that memory as if it was a double[][], even though the pointer type in the struct is a different one. Given a fractal f, the code for accessing through a pointer becomes something like this:
double (*array_2D)[width] = (double(*)[width]) f->values;
Where array_2D is an array pointer. The most correct type to use here would have been an array pointer to an array of double, double (*)[height][width], but that one comes with mandatory ugly accessing (*array_2D)[i][j]. To avoid such ugliness, a common trick is to leave out the left-most dimension in the array pointer declaration, then we can access it as array_2D[i][j] which looks far prettier.
Example code:
#include <stdlib.h>
#include <stdio.h>
typedef struct
{
char name[64];
size_t height;
size_t width;
double a;
double b;
double meanValue;
double values[];
} fractal_t;
fractal_t* fractal_create (size_t height, size_t width)
{
// using calloc since it conveniently fills everything with zeroes
fractal_t* f = calloc(1, sizeof *f + sizeof(double[height][width]) );
f->height = height;
f->width = width;
// ...
return f;
}
void fractal_destroy (fractal_t* f)
{
free(f);
}
void fractal_fill (fractal_t* f)
{
double (*array_2D)[f->width] = (double(*)[f->width]) f->values;
for(size_t height=0; height < f->height; height++)
{
for(size_t width=0; width < f->width; width++)
{
array_2D[height][width] = (double)width; // whatever value that makes sense
}
}
}
void fractal_print (const fractal_t* f)
{
double (*array_2D)[f->width] = (double(*)[f->width]) f->values;
for(size_t height=0; height < f->height; height++)
{
for(size_t width=0; width < f->width; width++)
{
printf("%.5f ", array_2D[height][width]);
}
printf("\n");
}
}
int main (void)
{
int h = 3;
int w = 4;
fractal_t* fractal = fractal_create(h, w);
fractal_fill(fractal); // fill with some garbage value
fractal_print(fractal);
fractal_destroy(fractal);
}
Dynamic dimensions arrays is not the point where C is at its best... Simple Variable Length Arrays were only introduced in the language in the C99 version and were made optional in C11 version. They are still not accepted in MSVC 2017...
But here, you are trying to set one in a struct. That is not supported at all because a struct must have a constant size(*) (how could be handled arrays of structs). So I am sorry but this code should not work and I know no way to express that in C language.
A common way would be to replace the 2D dynamic array with a pointer, allocate the pointer to a 2D array and then use it, but even this is not really simple.
You have to design your struct differently...
(*) The last element of a struct may be of an incomplete type, for example int tab[];. That is a dangerous feature because the programmer is responsable for providing room for it. But anyway you cannot build an array of incomplete types.
I encountered this problem while designing a struct to hold both the domain values (N x 1 vector) and the solution values (N x M matrix) in my ODE solver, so as to simplify the function interfaces. N and M are simulation-dependent and hence are unknown a priori. I solved it by using GNU Scientific Library's vector-matrix module. I found it more streamlined to work with than casting a FAM (albeit allocated as 2D) to a standalone whole-array-pointer.
After allocating memory for the struct, all we need to do is invoke gsl_matrix_alloc() to reserve space for the matrix. After we are done, calling gsl_matrix_free() will destroy it. Please note that these functions are data-type dependent as explained in the documentation.
Filename: struct_mat.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_statistics.h>
typedef struct _fractal {
char name[64];
size_t height;
size_t width;
double a;
double b;
double meanValue;
gsl_matrix *values;
} fractal;
fractal * fractal_create(size_t height, size_t width) {
fractal * fractalObj = (fractal *) malloc(sizeof(fractal));
fractalObj -> values = gsl_matrix_alloc(height, width);
if (fractalObj == NULL || fractalObj -> values == NULL) {
fprintf(stderr, "NULL pointer returned while allocating fractal object.. Exiting program.\n");
exit(EXIT_FAILURE);
}
fractalObj -> height = height;
fractalObj -> width = width;
fractalObj -> meanValue = 0.0;
return fractalObj;
}
void fractal_populate(fractal * fractalObj) {
srand(time(NULL));
double current_value = 0.0;
for (size_t r = 0; r < fractalObj -> height; ++r) {
for (size_t c = 0; c < fractalObj -> width; ++c) {
current_value = (double) rand() / (double) RAND_MAX;
gsl_matrix_set(fractalObj -> values, r, c, current_value);
}
}
}
void fractal_calcMeanValue(fractal * fractalObj) {
gsl_vector_view colVec;
for (size_t col = 0; col < fractalObj -> values -> size2; ++col) {
colVec = gsl_matrix_column(fractalObj -> values, col);
fractalObj -> meanValue += gsl_stats_mean(colVec.vector.data, colVec.vector.stride, colVec.vector.size);
}
fractalObj -> meanValue /= fractalObj -> values -> size2;
printf("\nThe mean value of the entire matrix is %lf\n", fractalObj -> meanValue);
}
void fractal_display(fractal * fractalObj) {
printf("\n");
for (size_t r = 0; r < fractalObj -> height; ++r) {
for (size_t c = 0; c < fractalObj -> width; ++c) {
printf("%lf ", gsl_matrix_get(fractalObj -> values, r, c));
}
printf("\n");
}
}
void fractal_delete(fractal * fractalObj) {
gsl_matrix_free(fractalObj -> values);
free(fractalObj);
}
int main(int argc, char const *argv[]){
// Program takes number of rows and columns as command line parameters
switch(argc) {
case 3:
printf("Running program..\n"); // to avoid the declaration-succeeding-label error
size_t height = atoi(argv[1]);
size_t width = atoi(argv[2]);
fractal * myFractal = fractal_create(height, width);
fractal_populate(myFractal);
fractal_display(myFractal);
fractal_calcMeanValue(myFractal);
fractal_delete(myFractal);
return 0;
default:
fprintf(stderr, "USAGE: struct_mat <rows> <columns>\n");
return 1;
}
}
Compile by linking with the GSL and GSL CBLAS libraries:
gcc -std=c99 struct_mat.c -o struct_mat -lgsl -lgslcblas -lm
You may install GSL via your distribution's package manager, Cygwin on Windows or by compiling the source.
In my limited experience, using a standard data structure proves to be far easier than wrestling with either FAMs or array-of-pointers-to-1D-arrays. However, the caveat is that we have to remember allocating memory for the matrix after allocating the struct itself.

dynamic allocation of 2d array function

So I have a program in C structured in 3 files: main.c, alloc.h and alloc.c. In the main.c function, I have the declaration of a pointer to another pointer to which I intend to alloc an n * m array:
#include <stdio.h>
#include <stdlib.h>
#include "alloc.h"
int main() {
int **mat, n, m;
alloc_matrix(&mat, int &n, int &m);
return 0;
}
In alloc.c I have the following declarations:
#ifndef ALLOC_H_INCLUDED
#define ALLOC_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
void alloc_matrix(int***, int*, int*);
#endif
In alloc.c I have the function:
void alloc_matrix(int ***mat, int *n, int *m) {
printf("\nn = "); scanf("%d", n);
printf("\nm = "); scanf("%d", m);
*mat = (int**)calloc(*n, sizeof(int*));
int i;
for (i = 0; i < *n; i++)
*(mat + i) = (int*)calloc(*m, sizeof(int));
}
But the program doesn't work. It enters some kind of loop and doesn't end.
If I allocate it in main it would work but I have no idea what I am doing wrong in the alloc function.
Here is the correct code. Your error was that in the definition of alloc_matrix, you used *(mat+i) in the allocation loop, which should be *(*mat+i) as, mat is a int*** so the base address for the 2D array would be in *mat. Then you need to move by offset i and then de-reference that memory location for the 1D array.
Main:
#include <stdio.h>
#include <stdlib.h>
#include "alloc.h"
int main()
{
int **mat,n,m;
alloc_matrix(&mat,&n,&m);
return 0;
}
alloc.h
#ifndef ALLOC_H_INCLUDED
#define ALLOC_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
void alloc_matrix(int***,int*,int*);
#endif
alloc.c :
void alloc_matrix(int ***mat,int *n,int *m)
{
printf("\nn = "); scanf("%d", n);
printf("\nm = "); scanf("%d", m);
*mat = (int**)calloc(*n,sizeof(int*));
int i;
for(i = 0; i < *n; i++)
*(*mat+i) = (int*)calloc(*m,sizeof(int));
}
The code for the read function :
void read_matrix(int ***mat,int n,int m)
{
int i,j;
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
{
printf("mat[%d][%d] = ", i, j);
scanf("%d", (*(*mat+i))+j);
}
}
The problem with it is that it only reads the first row and the it freezes.
void alloc_matrix(int ***mat,int *n,int *m)
There are two problems in this line. Neither is fatal but both are worth fixing.
First problem: A matrix in this program is represented as an int**. Why does alloc_matrix accept an int***? All standard functions that allocate something (malloc and friends) return a pointer to that something. This is an idiomatic way of doing things in C. It reduces your star count (being a three-star C programmer is not an achievement to be proud of) and simplifies the code. The function should be changed to
int** alloc_matrix( // but what's inside the () ?
The second problem is, why should a function called alloc_matrix prompt the user and read values? These things are not related to allocation. A function should do one thing and do it well. Does malloc prompts you to enter the size? Does fopen prompt you to enter the filename? These things would be regarded as nonsense of the first degree, and rightly so. It is advised to read the sizes elsewhere and pass them to alloc_matrix as input arguments. Hence,
int** alloc_matrix(int n, int m) { // but what's inside the {}?
What remains of alloc_matrix is simple:
int** alloc_matrix(int n, int m) {
int** mat; // that's what we will return
int i;
mat = (int**)calloc(n, sizeof(int*));
for(i = 0; i < n; i++)
// here comes the important part.
Since we have simplified alloc_matrixand reduced the star count in mat, what should we do with the old body of the loop? It was:
*(mat+i) = (int*)calloc(...);
but if we remove a star, it becomes
(mat+i) = (int*)calloc(...);
which is an obvious nonsense. Perhaps the old line was a problem. The fact that it provoked a compiler warning certainly doesn't speak for its correctness. So how to correct it? There aren't too many options. It turns out that in order to restore sanity, we must leave the old left-hand side (written for the three-star mat) intact. Or, better still, use an equivalent but more idiomatic notation:
mat[i] = (int*)calloc(m, sizeof(int));
So the entire function now becomes
int** alloc_matrix(int n, int m) {
int **mat;
int i;
mat = (int**)calloc(n, sizeof(int*));
for(i = 0; i < n; i++)
mat[i] = (int*)calloc(m, sizeof(int));
return mat;
}
and it should be called like
mat = alloc_matrix(n, m);
It is often said that one should not cast the result of calloc and friends. But in this case the cast has enabled a warning which helped to find a bug. I'm leaving the casts in place for now.
There is another idiom for the allocation that does not require the cast, but also avoids the problem of types not matching.
Instead of using the type for the sizeof, you can use the dereferenced pointer as the type information is available in the variable:
mat = (int**)calloc(n, sizeof(int*));
can be changed to
mat = calloc(n, sizeof *mat); //sizeof is an operator not a function

Wrong results with dynamic memory allocation

I am trying to find out the Lagrange's Interpolation with the program. I have solved it using arrays but when using dynamic memory allocation, the program is giving me garbage result.
#include<stdio.h>
#include<conio.h>
#define SIZE 100
int main()
{
float *x,*y;
float value = 0,ask,temp;
int i,j,n;
printf("Enter size");
scanf("%d",&n);
x = (float*)malloc(n*sizeof(float));
y = (float*)malloc(n*sizeof(float));
for(i = 0; i < n;i++)
{
printf("x[%d]: ",i);
scanf("%f",(x+i));
printf("y[%d]: ",i);
scanf("%f",(y+i));
}
printf("Enter value to find");
scanf("%f",&ask); //cin >> ask;
for(i = 0; i < n;i++)
{
temp = 1;
for(j = 0; j < n; j++)
{
if(i != j)
{
temp = temp * (ask-(*(x+i))/(*(x+i)-*(x+j)));
}
}
value = value + temp * *(y+i);
}
printf("%f",value);
}
You need to #include <stdlib.h>, since that is the header that declares functions that perform dynamic memory allocation (malloc(), etc).
You will find, assuming you use a C compiler and not a C++ compiler, that the type conversions on the malloc() calls are not required.
x = (float*)malloc(n*sizeof(float)); /* (float *) is unnecessary */
The problem is that, without stdlib.h, the compiler assumes malloc() returns an int. The type conversion might allow the code to compile without stdlib.h, but the result is subsequent usage of the malloc()d pointer will have undefined behaviour, since the pointer does not necessarily survive the round trip (being converted to int and then back).
If you are using a C++ compiler, then the (float *) type conversion AND #include <stdlib.h> are BOTH required to avoid undefined behaviour.

How do I dump an arbitrary struct in C?

I don't know which direction to go,perhaps something like reflection will help?
If you're using Clang 8 or newer, you can now use the built-in compiler function __builtin_dump_struct to dump a struct. It uses the information that's naturally available at compile time to generate code that pretty-prints a struct.
Example code demonstrating the function:
dumpstruct.c:
#include <stdio.h>
struct nested {
int aa;
};
struct dumpme {
int a;
int b;
struct nested n;
};
int main(void) {
struct nested n;
n.aa = 12;
struct dumpme d;
d.a = 1;
d.b = 2;
d.n = n;
__builtin_dump_struct(&d, &printf);
return 0;
}
Example compile-and-run:
$ clang dumpstruct.c -o dumpstruct
$ ./dumpstruct
struct dumpme {
int a : 1
int b : 2
struct nested n : struct nested {
int aa : 12
}
}
If you're not using Clang >= 8 but you are using GCC, it's pretty easy to switch. Just install the clang-8 or clang-9 package and replace invocations of gcc with clang.
The answer of #Kerrek SB works realy well, I just post how to use it in a function using a void pointer.
int dump(void *myStruct, long size)
{
unsigned int i;
const unsigned char * const px = (unsigned char*)myStruct;
for (i = 0; i < size; ++i) {
if( i % (sizeof(int) * 8) == 0){
printf("\n%08X ", i);
}
else if( i % 4 == 0){
printf(" ");
}
printf("%02X", px[i]);
}
printf("\n\n");
return 0;
}
int main(int argc, char const *argv[])
{
OneStruct data1, data2;
dump(&data1, sizeof(OneStruct));
dump(&data2, sizeof(OneStruct));
return 0;
}
Here's a hex dump, about as general as you can get:
struct Foo x;
unsigned int i;
const unsigned char * const px = (unsigned char*)&x;
for (i = 0; i < sizeof(x); ++i) printf("%02X ", px[i]);
Note that the result of this is entirely implementation-defined; presumably there'll be plenty of padding, and you won't know what any of the printed values mean. (Most of them will probably just be pointers to some other part of space.)
As Etienne says, C is a statically typed language and does not have reflection, so you have to know the declaration of Foo in order to interpret the content of x.
What do you want to do with your file once you've got it? If it's going to be read back in at a later time just use fread and fwrite, like
struct foo * bar;
fwrite(bar,sizeof(*bar),1,stdout);
...
fread(bar,sizeof(*bar),1,stdin);
This will give binary output that's dependant on your compiler/platform, as long as those are unchanged you should be fine. From there you can also feed the file into a hex reader etc., though you'll need to know the layout of the struct to do anything useful with it.

Resources