Memcpy or struct assignment? - c

I have the following code and am unsure of whether to use structure alignment or memcpy to copy struct A onto the custom "stack" char/byte array.
Is there anything advantageous/disadvantageous about the following two options of code or anything that is just flat out wrong?
The necessary struct/functions.
struct B {
int type;
struct B *prev;
}
struct A {
struct B base;
int n;
struct B *another;
char name[1]; /* Struct hack */
};
void align(char **ptr, int n) {
intptr_t addr = (intptr_t)*ptr;
if(addr % n != 0) {
addr += n - addr % n;
*ptr = (char *)addr;
}
}
Option 1: Struct Assignment
void struct_assignment() {
char *stack = malloc(400*1000);
char *top_of_stack = stack + 3149; /* Just an example */
struct A *var = (struct A *)top_of_stack;
align((char **)&var, sizeof(struct B)); /* Most restrictive alignment member in struct A */
var->base.type = 1;
var->base.prev = NULL;
var->another = (struct base *)var;
char *name = "test";
var->n = strlen(name) + 1;
strcpy(var->name, name);
top_of_stack = (char*)var + sizeof(*var)+ (var->n - 1); /* -1 for name[1] */
}
Option 2: memcpy
void memcpying() {
char *stack = malloc(400*1000);
char *top_of_stack = stack + 3149; /* Just an example */
struct A var;
var.base.type = 1;
var.base.prev = NULL;
var.another = NULL;
char *name = "test";
var.n = strlen(name) + 1;
strcpy(var.name, name);
char *aligned_ptr = top_of_stack;
align(&aligned_ptr, sizeof(struct B)); /* Most restrictive alignment member in struct A */
memcpy(aligned_ptr, &var, sizeof(var) + (var.n - 1); /* -1 for name[1] */
struct A *var_ptr = (struct A*)aligned_ptr;
var_ptr->another = (struct B *)var_ptr;
top_of_stack = aligned_ptr + sizeof(var)+ (var.n - 1); /* -1 for name[1] */
}
Is option 1 even struct assignment?
Will both options result in the same padding and alignment?
Will the endianness of the target architecture affect option 1?

I don't think that this can be called struct assignment. You are assigning to the individual fields.
struct assingment in your case where you are merely interested in initialization of the object on the stack that you are "reserving" could use a temporary:
struct base tmp = {
.type = 1,
.prev = NULL,
// whatever other fields you want to initialize
};
var->base = tmp;
or even more consise by using a compound literal:
var->base = (struct base){
.type = 1,
.prev = NULL,
// whatever other fields you want to initialize
};
Both methods have the advantage of initializing all fields that you
might have forgotten to 0. The for the copy operation itself, let the compiler chose whatever the compiler designer saw fit. Don't mess around with such things unless some careful benchmarking tells you that there is a real problem.

Related

calloc allocatin 0 bytes for a struct field

Heyo,
I have problem allocating memory for my "database"
i have this struct
typedef struct TPrvek {
struct TPrvek *parent1;
struct TPrvek *parent2;
int id;//key
char *name;//value
} TPrvek;
typedef struct Database {
int size;
struct TPrvek **TField;
} DATABASE;
and I am initializing like this :
void init(DATABASE *db) {
DATABASE *newDb = (DATABASE *) malloc(sizeof(DATABASE));
newDb->size = 1000;//initial capacity
newDb->TField = (TPrvek **) calloc(newDb->size, sizeof(TPrvek *));
for (int i = 0; i < db->size; i++) {
newDb->TField[i] = NULL;
}
*db = *newDb;
}
But when i try to insert smth to it, im writing out of allocated memmory and I don't know how to repair it nor what is even wrong
snipet of insertion:
int addPerson(DATABASE *db,
int id,
const char *name,
int id1,
int id2) {
//some checks to make sure ids are in bounds and field for new person is empty
TPrvek *clovek = (TPrvek *) malloc(sizeof(TPrvek));
clovek->name = (char *) malloc(sizeof(name) + 1);
strcpy(clovek->name, name);
clovek->id = id;
//clovek->parent1 = (TPrvek *) malloc(sizeof(TPrvek));
//clovek->parent2 = (TPrvek *) malloc(sizeof(TPrvek));I was desperate, this is wrong I think
clovek->parent1 = db->TField[id1];
clovek->parent2 = db->TField[id2];
db->TField[id] = clovek;
//returns 1 if success
}
and in the main I have simple asserts to check functionality like :
int main(int argc,
char *argv[]) {
DATABASE a;
init(&a);
assert (addPerson(&a, 1, "John", 0, 0) == 1);
assert (addPerson(&a, 2, "Caroline", 0, 0) == 1);
...}
Any ideas?
I'm pretty new to c and memory allocating in general, so I would be glad for every bit of help :)
This line is the problem (at least one I see straight away):
clovek->name = (char *) malloc(sizeof(name) + 1);
Type of name is char *, and sizeof(char *) is size of pointer - always 8.
What you need instead is the length of string, i.e:
clovek->name = (char *) malloc(strlen(name) + 1);

How to fix strange behavior of anonymously created structure, when called in function?

I'm trying to recreate an encapsulation principle in ANSI-C for educational purposes. What I essentially did was making some structure in .c file:
struct _private
{
unsigned char SizeInBytes;
unsigned char* matrix;
struct Stack* S;
unsigned char ByteX;
};
which represented variables I wanted to be unseen. Then in .h file inside the struct (class) I created an opaque pointer:
struct Maze
{
void* _private;
};
which I assign later in constructor function like this:
void* Maze_ctor(void* self, va_list *ap)
{
struct Maze* this = self;
this->DimX = va_arg(*ap, unsigned char);
this->DimY = va_arg(*ap, unsigned char);
this->_private = &(struct _private) // passing address of struct to void*
{
.SizeInBytes = this->DimX*this->DimY >> 1,
.S = new(Stack),
.ByteX = this->DimX % 8 > 0 ? this->DimX / 8 + 1 : this->DimX / 8
};
//
private.matrix = (unsigned char*)malloc(private.ByteX*this->DimY);
S = new(Stack); // this in my new() and it works similar to C++ new
for (int i = 0; i < private.ByteX*this->DimY; i++)
*(private.matrix + i) = 0;
}
At this point everything works fine, but then I'm trying to call the Next() method:
int Next(void* self, ...)
{
struct Maze* this = self;
struct _private *r = this->_private;
short t;
toBinary(this); // after this point the struct private breaks
}
the prototype of toBinary() is:
void toBinary(const void* self)
{
// somehow char local is defined and equals to 204??
struct Maze *this = self;
struct _private *r = this->_private;
unsigned char local; // right after this point SizeInBytes equals to 204!
...
}
the question is: how to fix this problem. Using C++ is prohibited!
for the interested ones: here is new()
void* new(const void* _class,...)
{
const struct Class* class = _class; // we need to convert pointer from void* to class* safely
void *p = calloc(1, class->size); // allocation of memory for class .using size param
assert(p); // if Null -> throw an error
*(const struct Class**)p = class; // safe assignment of class pointer to (value) of p, to have memory and built in funcs
if (class->ctor) // if has constructor with some dynal in it, execute with varargs on its input
{
va_list ap;
va_start(ap, _class); //
p = class->ctor(p, &ap); // pass arguments as a list of pointers.
va_end(ap);
}
return p; //returns a pointer to class pointer (weird but worx)
}
As pointed out in the comment, the problem is that you created a local object and assign it to a pointer this. Outside that function, the value of this is not valid.
You code,
void* Maze_ctor(void* self, va_list *ap)
{
//....
// this creates a temporary object and will be destroyed after Maz_ctor returns.
this->_private = &(struct _private) // passing address of struct to void*
{
.SizeInBytes = this->DimX*this->DimY >> 1,
.S = new(Stack),
.ByteX = this->DimX % 8 > 0 ? this->DimX / 8 + 1 : this->DimX / 8
};
// ---
}
Thanks to #Sami Kuhmonen for pointing out on dynamic allocation and #CS Pei for mistake analysis. The thing I did to fix this is:
struct Maze
{
char _private[32]; // allocate the memory size of struct(32)
}
// assign values to void ptr
private.SizeInBytes = this->DimX*this->DimY >> 1;
private.S = new(Stack);
private.ByteX = this->DimX % 8 > 0 ? this->DimX / 8 + 1 : this->DimX / 8;
private.matrix = (unsigned char*)malloc(private.ByteX*this->DimY);
this now works as intended, but a little slower

C Return Struct Pointer after Function Call Value Gets Lost

I'm trying to figure out why my struct value is lost after the function return.
struct A {
int val1;
int val2;
}
main() {
struct A *a;
a->val1 = 1;
a->val2 = 2;
calc((void*)a);
// calc returns and a's values are 1 and 2 respectively
}
void calc(void* v) {
struct A *a = (struct A*) v;
...
a->val1 = 2;
a->val2 = 3;
}
When you want to deal with pointers, you have to introduce dynamic memory allocation. Creating a pointer means you are telling compiler that 'I am going to store address of variable in it'. So in this case, either you create an object assign address to it or allocate memory to it dynamically.
Case 1:
main() {
struct A *a;
struct A obj;//assign address of other object manually
a = &obj;
a->val1 = 1;
a->val2 = 2;
calc((void*)a);
// calc returns and a's values are 1 and 2 respectively
}
Case 2:
main() {
struct A *a;
a = (A *) malloc(sizeof(A));//dynamic memory allocation
a->val1 = 1;
a->val2 = 2;
calc((void*)a);
// calc returns and a's values are 1 and 2 respectively
}

Memory out of bounds once function exits despite heap allocation?

General problem: implementing a dictionary.
Specific problem: according to gdb, my allocations and everything are working exactly as intended. The problem arises once types_dict_add is called with a key of "c". Everything is once again allocated as it should be and the entire dictionary is intact throughout the function context (all pointers are accessible and the structures at those pointers have their set values), but once the function exits back to main, the mydict pointers are all out of bounds. The actual pointer addresses stored in the mydict are all unchanged, but are suddenly inaccessible. Up until the call with "c", the mydict is also intact and as it should be in main.c
What am I doing wrong here? It's really confusing me as I've checked with gdb over and over again and the len value is being set correctly so there is definitely a proper amount of space being realloc'd each go.
types.h
#ifndef _TYPES_H_
#define _TYPES_H_
union types {
long int ival;
char *sval;
};
struct kv {
char* key;
union types val;
};
struct kv **types_dict_init();
void types_dict_add(struct kv**, char*, union types);
struct kv *types_dict_get(char*);
void types_dict_free(struct kv**);
#endif
types.c
struct kv **
types_dict_init()
{
struct kv **newdict;
newdict = calloc(1, sizeof(struct kv*));
newdict[0] = NULL;
return (newdict);
}
void
types_dict_add(struct kv** d, char* k, union types v)
{
int len;
if (d[0] == NULL) {
d = realloc(d, sizeof(struct kv*) * 2);
d[0] = malloc(sizeof(struct kv));
d[0]->key = k;
d[0]->val = v;
d[1] = NULL;
} else {
for (len = 1; d[len - 1] != NULL; len++)
;
d = realloc(d, sizeof(struct kv*) * ++len);
d[len - 2] = malloc(sizeof(struct kv));
d[len - 2]->key = k;
d[len - 2]->val = v;
d[len - 1] = NULL;
}
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "bencode/types.h"
int main(int argc, char **argv)
{
struct kv **mydict;
union types toadd;
toadd.sval = "test";
mydict = types_dict_init();
types_dict_add(mydict, "a", toadd);
types_dict_add(mydict, "b", toadd);
types_dict_add(mydict, "c", toadd);
types_dict_add(mydict, "d", toadd);
for(int i = 0; i < 4; i++)
printf("%d: %s\n", i, mydict[i]->key);
return (EXIT_SUCCESS);
}
In types_dict_add you modify the local variable d. This change is not reflected in main's variable mydict, because C passes function arguments by value. You will need to add an extra level of indirection if you want types_dict_add to be able to do realloc on mydict.
I think it would be simpler to use length-counting instead of a terminating NULL; then you can make your controlling structure be something like:
struct dict
{
struct kv **members;
size_t n_members;
};
This would also avoid a triple pointer (some people are uncomfortable with those).
Always check the return value of realloc. realloc may fail in some cases.
d = realloc(d, sizeof(struct kv*) * 2);
do the check before accessing d.

array of type void

plain C have nice feature - void type pointers, which can be used as pointer to any data type.
But, assume I have following struct:
struct token {
int type;
void *value;
};
where value field may point to char array, or to int, or something else.
So when allocating new instance of this struct, I need:
1) allocate memory for this struct;
2) allocate memory for value and assign it to value field.
My question is - is there ways to declare "array of type void", which can be casted to any another type like void pointer?
All I want is to use "flexible member array" (described in 6.7.2.1 of C99 standard) with ability to casting to any type.
Something like this:
struct token {
int type;
void value[];
};
struct token *p = malloc(sizeof(struct token) + value_size);
memcpy(p->value, val, value_size);
...
char *ptr = token->value;
I suppose declaring token->value as char or int array and casting to needed type later will do this work, but can be very confusing for someone who will read this code later.
Well, sort of, but it's probably not something you want:
struct token {
// your fields
size_t item_size;
size_t length
};
struct token *make_token(/* your arguments */, size_t item_size, size_t length)
{
struct token *t = malloc(sizeof *t + item_size * length);
if(t == NULL) return NULL;
t->item_size = item_size;
t->length = length;
// rest of initialization
}
The following macro can be used to index your data (assuming x is a struct token *):
#define idx(x, i, t) *(t *)(i < x->length ? sizeof(t) == x->item_size ?
(void *)(((char *)x[1]) + x->item_size * i)
: NULL : NULL)
And, if you like, the following macro can wrap your make_token function to make it a little more intuitive (or more hackish, if you think about it that way):
#define make_token(/* args */, t, l) (make_token)(/* args */, sizeof(t), l)
Usage:
struct token *p = make_token(/* args */, int, 5); // allocates space for 5 ints
...
idx(p, 2, int) = 10;
Expanding on AShelly's answer you can do this;
/** A buffer structure containing count entries of the given size. */
typedef struct {
size_t size;
int count;
void *buf;
} buffer_t;
/** Allocate a new buffer_t with "count" entries of "size" size. */
buffer_t *buffer_new(size_t size, int count)
{
buffer_t *p = malloc(offsetof(buffer_t, buf) + count*size);
if (p) {
p->size = size;
p->count = count;
}
return p;
}
Note the use of "offsetof()" instead of "sizeof()" when allocating the memory to avoid wasting the "void *buf;" field size. The type of "buf" doesn't matter much, but using "void *" means it will align the "buf" field in the struct optimally for a pointer, adding padding before it if required. This usually gives better memory alignment for the entries, particularly if they are at least as big as a pointer.
Accessing the entries in the buffer looks like this;
/** Get a pointer to the i'th entry. */
void *buffer_get(buffer_t *t, int i)
{
return &t->buf + i * t->size;
}
Note the extra address-of operator to get the address of the "buf" field as the starting point for the allocated entry memory.
I would probably do this:
struct token {
int type;
void *value;
};
struct token p;
p.value = malloc(value_size);
p.value[0] = something;
p.value[1] = something;
...
edit, actually you have to typecast those p.value[index] = somethings. And/or use a union to not have to typecast.
You can't have an array of 'void' items, but you should be able to do something like what you want, as long as you know value_size when you do the malloc. But it won't be pretty.
struct token {
int type;
void *value;
};
value_size = sizeof(type)*item_count;
struct token *p = malloc(sizeof(struct token) + value_size);
//can't do memcpy: memcpy(p->value, val, value_size);
//do this instead
type* p = (type*)&(p->value);
type* end = p+item_count;
while (p<end) { *p++ = someItem; }
Note that you need an extra address-of operator when you want to get the extra storage.
type *ptr = (type*)&(token->value);
This will 'waste' sizeof(void*) bytes, and the original type of value doesn't really matter, so you may as well use a smaller item. I'd probably typedef char placeholder; and make value that type.
following structure can help you.
struct clib_object_t {
void* raw_data;
size_t size;
};
struct clib_object_t*
new_clib_object(void *inObject, size_t obj_size) {
struct clib_object_t* tmp = (struct clib_object_t*)malloc(sizeof(struct clib_object_t));
if ( ! tmp )
return (struct clib_object_t*)0;
tmp->size = obj_size;
tmp->raw_data = (void*)malloc(obj_size);
if ( !tmp->raw_data ) {
free ( tmp );
return (struct clib_object_t*)0;
}
memcpy ( tmp->raw_data, inObject, obj_size);
return tmp;
}
clib_error
get_raw_clib_object ( struct clib_object_t *inObject, void**elem) {
*elem = (void*)malloc(inObject->size);
if ( ! *elem )
return CLIB_ELEMENT_RETURN_ERROR;
memcpy ( *elem, inObject->raw_data, inObject->size );
return CLIB_ERROR_SUCCESS;
}
More Details : clibutils
Array of type void is not supporting in c/c++.
Example like:
int main() {
void alexa[]; // error: declaration of ‘alexa’ as array of void
return 0;
}
Array of void pointer is supported in c/c++.
Example below:
int main(int argc, char argv*[])
{
void *alexa[100]; // Compiled successfully
return 0;
}

Resources