I have a function that writes custom structs to some kind of "data block" (struct) that I created, which contains a void pointer that can store a custom struct. I created a function to write and to read to that specific void pointer but unfortunately, the first element of the returned struct always returns as "80" instead of it's original value. Here's the code:
#include <stdio.h>
#include <malloc.h>
typedef struct dataBlock {
void* dataObject;
} DataBlock;
typedef struct testingStruct {
int testingInt1;
int testingInt2;
}TestObject;
void dataWriter(DataBlock *dataBlock, void* inputObject, int objSize) {
if (objSize > 255) {
printf("Error. Maximum 255 Bytes of data can be stored.");
exit(0);
}
dataBlock->dataObject = malloc(objSize+1); // Allocates the size of dataObject plus one byte to store the size of the data Object.
((char*)dataBlock->dataObject)[0] = (char)objSize; //Stores the size of the data object to position 0 in the void*
for (int i = 1; i < objSize; ++i) {
((char*)dataBlock->dataObject)[i] = (char)((char*)inputObject)[i];
}
}
void* dataGetter(DataBlock *dataBlock) {
void* dataToReturn = malloc(((int)((char*)dataBlock->dataObject)[0])); // Creates Container to store read data using Void* Pos 0 in dataObject
for (int i = 1; i < (int)(((char*)dataBlock->dataObject)[0]); ++i) {
((char*)dataToReturn)[i] = (char)((char*)dataBlock->dataObject)[i]; //writes each byte of data to return to dataToReturn
}
return dataToReturn;
}
int main() {
TestObject *testObject = malloc(sizeof(TestObject));
testObject->testingInt1 = 74;
testObject->testingInt2 = 49;
DataBlock *dataBlockToStore = malloc(sizeof(DataBlock));
dataWriter(dataBlockToStore, testObject, sizeof(TestObject));
TestObject *testObjectCpy = dataGetter(dataBlockToStore); // Reads data from Block and generates another TestObject
printf("%d\n", testObjectCpy->testingInt1); // Should be 74
printf("%d\n", testObjectCpy->testingInt2); // Returned Correctly
return 0;
}
I am unsure, if I am either reading or writing the data in the wrong way but the first variable in the written testingStruct always returns a wrong value.
for (int i = 1; i < objSize; ++i) {
((char*)dataBlock->dataObject)[i] = (char)((char*)inputObject)[i];
Array indices are zero-based. You are skipping the first element.
You need to do e.g. (avoid i and 'l' in loops when adding 1.....)
for (int j = 0; j < objSize; ++j) {
((char*)dataBlock->dataObject)[j+1] = (char)((char*)inputObject)[j];
You could alternatively use memcpy.
You should also assert/fail if the size is above 255
Also, if you make dataBlock a char* you will need to perform less casting.
Related
I've created this struct, and a function that initializes all of the fields within that struct and returns a struct pointer. Within this struct I have one single dimensional array of integers, and a two dimensional array of pointers. However, when initialing and incrementing the value inside the cells inside party->fragment_sizes[I] (single dimensional array), party->fragment_sizes[] also begins to increment (two dimensional array). Party->fragment_sizes[i] goes from NULL (0x0) to (0x10000), (0x2000000) I have no idea how, but it's messing me up pretty badly. I need party_fragments_sizes to remain NULL until allocated (inside another function).
#include <stdio.h>
#include <stdlib.h>
typedef struct LonelyPartyArray
{
int **fragments; // the address of fragments[i] is being set as
int *fragment_sizes; // the value inside fragment_sizes[i]
} LonelyPartyArray;
LonelyPartyArray *createParty(int num_fragments)
{
int i;
// Allocating LonelyPartyArray struct pointer
LonelyPartyArray *party = malloc(sizeof(LonelyPartyArray));
// I am allocating these separately,
// is something going on with how my system is
// allocating space for these arrays?
// Allocating LonelyPartyArray
party->fragments = malloc(sizeof(int *) * num_fragments);
// Allocating LonelyPartyArray fragment size
party->fragment_sizes = malloc(sizeof(int) * num_fragments);
// Initializing party->fragments to NULL (not used) and fragment_sizes to zero
for (i = 0; i < num_fragments; i++)
party->fragments[i] = NULL;
for (i = 0; i < num_fragments; i++)
party->fragment_sizes[i] = 0;
// Party->fragments[I] is not remaining NULL, but is being
// incremented. (I.e., party-fragments[I] increments 0x0,
// 0x10000, 0x20000, 0x30000 etc). This needs to remain NULL.
for (i = 0; i < num_fragments; i++)
{
if (party->fragments[i] != party->fragment_sizes[i])
break;
printf("Why is this happening???? [%d]\n", i);
printf("%p\n, party->fragments[i]);
}
return NULL;
}
int main(void)
{
LonelyPartyArray *party = createParty(3);
return 0;
}
I have no idea how party->fragments[] is being set as the address for party->fragment_sizes[], but I need them to be separate.
Since the array address may change when memory is reallocated,
the main part of the program (in the body of the function main ()) should refer to the elements by
indexes, not pointers. Why?
Can you show an example of accessing items with pointers?
(Sorry for my English).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Nameval Nameval;
struct Nameval {
char *name;
int value;
};
struct NVtab {
int nval; /* current number of values */
int max; /* allocated number of values */
Nameval *nameval; /* array of name-value pairs */
};
enum {NVINIT = 1, NVGROW = 2};
/* addname: add new name and value to nvtab */
int addname(struct NVtab *nvtab, Nameval newname) {
Nameval *nvp;
if (nvtab->nameval == NULL) { /* first time */
nvtab->nameval = (Nameval *) malloc(NVINIT * sizeof(Nameval));
if (nvtab->nameval == NULL)
return -1;
nvtab->max = NVINIT;
nvtab->nval = 0;
} else if (nvtab->nval >= nvtab->max) { /* grow */
nvp = (Nameval *) realloc(nvtab->nameval,
(NVGROW*nvtab->max)*sizeof(Nameval));
if (nvp == NULL)
return -1;
nvtab->max *= NVGROW;
nvtab->nameval = nvp;
}
nvtab->nameval[nvtab->nval] = newname;
return nvtab->nval++;
}
int main(void) {
struct NVtab nvtab = {0, 0, NULL};
int curnum;
curnum = addname(&nvtab, (Nameval) {.name="Andy", .value=12});
printf("%d\n", curnum);
curnum = addname(&nvtab, (Nameval) {.name="Billy", .value=18});
printf("%d\n", curnum);
curnum = addname(&nvtab, (Nameval) {.name="Jack", .value=71});
printf("%d\n", curnum);
for (int i = 0; i < nvtab.nval; i++) {
printf("%s %d\n", nvtab.nameval[i].name,
nvtab.nameval[i].value);
}
}
For example, why can`t we show array like this:
for (int i = 0; i < nvtab.nval; i++)
printf("%s %d\n", nvtab.*(nameval+i).name, nvtab.*(nameval+i).value);
You are not supposed to assign a pointer calculated for a specific index to a variable with storage duration which could extend over an insert operation.
That pointer could become invalid, so the lesson behind that example is to always re-evaluate iterators on dynamic data structures.
E.g. what not to do:
auto *foo = &nvtab.nameval[i];
addname(&nvtab, (Nameval) {.name="Billy", .value=18});
printf("%s %d\n", foo->name, foo->value);
In the last line it can work or crash. Depending on whether realloc moved the allocation or resized in-place. Except that you can never know for sure until you execute it, as it isn't even fully deterministic.
This is not valid syntax:
nvtab. *(nameval+i).name
The member access operator . expects to be followed by the name of the member. What you want is:
(*(nvtab.nameval+i)).name
As stated in the question, is it possible to create a structure within a function, and then return that structure when the function exits? Since the structure is not created until the function is called, I don't know what to put in the prototype for the return value. Any advice/help would be great, thanks.
static void section_to_segment_map(Elf *elf, GElf_Ehdr *ehdr) {
struct memory_data {
int phdr_addrs[ehdr->e_phnum][2];
int section_bounds[ehdr->e_shnum][2];
} memData;
for(int phead_cnt = 0; phead_cnt < ehdr->e_phnum; phead_cnt++) {
GElf_Phdr mem;
GElf_Phdr *phdr = gelf_getphdr(elf, phead_cnt, &mem);
memData.phdr_addrs[phead_cnt][1] = phdr->p_vaddr;
memData.phdr_addrs[phead_cnt][2] = phdr->p_vaddr + phdr->p_memsz;
}
printf("Starting and Ending Address Values for Program Segments:\n");
for(int i = 0; i < ehdr->e_phnum; i++)
printf("%x --> %x\n", memData.phdr_addrs[i][1], memData.phdr_addrs[i][2]);
Elf_Scn *scn = NULL;
for(int shead_cnt = 0; shead_cnt < ehdr->e_shnum; shead_cnt++) {
scn = elf_getscn(elf, shead_cnt);
GElf_Shdr shdr_mem;
GElf_Shdr *shdr = gelf_getshdr(scn, &shdr_mem);
memData.section_bounds[shead_cnt][1] = shdr->sh_addr;
memData.section_bounds[shead_cnt][2] = shdr->sh_addr + shdr->sh_size;
}
printf("\n");
printf("Starting and Ending Addresses for Program Sections:\n");
for(int j = 0; j < ehdr->e_shnum; j++)
printf("%x --> %x\n", memData.section_bounds[j][1], memData.section_bounds[j][2]);
return memData;
}
Return a structure that was created within a function?
is it possible to create a structure within a function, and then return that structure ..?
No. The return type must be defined before the function body.
// void section_to_segment_map(Elf *elf, GElf_Ehdr *ehdr) {
struct memory_data section_to_segment_map(Elf *elf, GElf_Ehdr *ehdr) {
Yet OP's struct has a variable size and so defining the struct ahead of time fails.
struct memory_data {
// fails "error: variably modified 'phdr_addrs' at file scope"
int phdr_addrs[some_variable][2];
...
} memData;
A fixed sized struct would work, yet may be inefficient if large.
#define MEMORY_DATA_N_MAX 10
struct memory_data {
int phdr_addrs[MEMORY_DATA_N_MAX][2];
...
} memData;
Various dynamic options exist such as creating a struct that contains the size information and pointers to allocated space. This obliges section_to_segment_map() to allocate memory and the caller to insure it is free'd.
struct memory_data {
size_t sz;
int (*phdr_addrs)[2];
int (*section_bounds)[2];
} memData;
First of all, in order to return a structure from you function you need to declare it outside of the functions scope, so other functions would be able to use it as well.
/* You can change this size if you wish */
#define PHDR_ADDRESS_SIZE (0xffff)
struct memory_data {
int phdr_addrs[PHDR_ADDRESS_SIZE][2];
int section_bounds[PHDR_ADDRESS_SIZE][2];
} memData;
static void section_to_segment_map(Elf *elf, GElf_Ehdr *ehdr)
{
/* Code... */
}
int main(void)
{
memData m = {};
}
In order to return a structure from your function, you have two main options.
Actually return the structre
You need to cahnge the return value of the function to be from the type "memData" instead of "void". Then, you can just return that value.
For example:
memData section_to_segment_map(Elf *elf, GElf_Ehdr *ehdr)
{
memData m = {};
/* Code... */
return m;
}
Pass an out parameter to the function
Another option, which is more reccomended in my opinion is to pass an out parameter to the function, which is a pointer.
You need to pass a pointer to memData, and the you can change it inside your function. For example:
void section_to_segment_map(Elf *elf, GElf_Ehdr *ehdr, memData* m)
{
for(int phead_cnt = 0; phead_cnt < ehdr->e_phnum; phead_cnt++) {
GElf_Phdr mem;
GElf_Phdr *phdr = gelf_getphdr(elf, phead_cnt, &mem);
*memData.phdr_addrs[phead_cnt][1] = phdr->p_vaddr;
*memData.phdr_addrs[phead_cnt][2] = phdr->p_vaddr + phdr->p_memsz;
}
/* More of the code.... */
return;
}
In order to call the function from main, you should do the following:
int main(void)
{
memData m = {};
/* Put your own arguments isntead of <elf>, <edhr> */
section_to_segment_map(<elf>, <ehdr>, &m);
}
While playing with the implementation of a hashmap toy example (for fun) I've found a strange behaviour, calloc does not initialize the entire memory block I want to zero, as supposed to do. The following code should produce no output if the entire memory block is zeroed:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define DICT_INITIAL_CAPACITY 50
typedef struct dictionary_item {
char* ptr_key;
void* ptr_value;
} dict_item;
typedef struct dictionary {
dict_item* items;
uint16_t size, max_capacity;
} Dict;
Dict* dict_new() {
Dict *my_dict = calloc(1, sizeof *my_dict);
my_dict->items = calloc(DICT_INITIAL_CAPACITY, sizeof my_dict->items);
my_dict->size = 0;
my_dict->max_capacity = DICT_INITIAL_CAPACITY;
for (int j = 0; j < my_dict->max_capacity; j++) {
int key_null = 1;
int value_null = 1;
if ((my_dict->items + j)->ptr_key != NULL)
key_null = 0;
if ((my_dict->items + j)->ptr_value != NULL)
value_null = 0;
if ((my_dict->items + j)->ptr_key != NULL || (my_dict->items + j)->ptr_value != NULL)
printf("item %d, key_null %d, value_null %d\n", j, key_null, value_null);
}
return my_dict;
}
int main(int argc, char** argv) {
Dict* dict = dict_new();
}
However it produces the output:
item 25, key_null 1, value_null 0
The only non-zero item is always the one at DICT_INITIAL_CAPACITY / 2. I've tried also using memset to put all the block to zero and the result is the same. If I put the memory to zero explicitly using:
for (int j = 0; j < my_dict->max_capacity; j++){
(my_dict->items + j)->ptr_key = 0;
(my_dict->items + j)->ptr_value = 0;
}
Then I get the desired behavior. But I do not understand why it does not work using calloc. What am I doing wrong?
my_dict->items = calloc(DICT_INITIAL_CAPACITY, sizeof my_dict->items);
Should be
my_dict->items = calloc(DICT_INITIAL_CAPACITY, sizeof *my_dict->items);
Also note that, in general, calloc may not set pointers to null (although it does on all modern systems that I know of). It would be safer to explicitly initialize any pointers that are meant to be null.
Having said that, you seem to be storing a size variable to indicate the size of the dictionary, so you could avoid this problem entirely by not reading entries beyond the current size; and when you do increase size then initialize the entries you have just added.
const static int VECTOR_BASIC_LENGTH = 20;
struct m_vector
{
void* my_vector;
size_t my_capacity;
size_t my_head;
};
typedef struct m_vector Vector;
Vector creat_Vector(size_t size,void *judge)
{
Vector _vector;
size = size?size:VECTOR_BASIC_LENGTH;
_vector.my_capacity = size;
_vector.my_head = 0;
//How I write the following two lines
_vector.my_vector = malloc(sizeof(*judge) * size);
return _vector;
}
The type of judge is uncertain,so I pass a void pointer as a parameters.I need the size of *judge to allocate memory to _vector.my_vector,for example if I use:
int *a;
creat_Vector(5,a);
I want the following line:
_vector.my_vector = malloc(sizeof(*judge)*size);
is equal to:
_vector.my_vector = malloc(sizeof(*a)*5);
How could I achieve this function.Using pure C
There is a forbidden thing done in your code.
You statically (at compile time) allocate/declare a local _vector of type Vector in your function creat_Vector. Then you return this object to the outside world. However, when you are exiting your function, all local data is dead. So, you should absolutely rethink this.
One suggestion would be:
int init_Vector(Vector* _vect, size_t size, unsigned int ptr_size)
{
size = size?size:VECTOR_BASIC_LENGTH;
_vect->my_capacity = size;
_vect->my_head = 0;
_vect->my_vector = malloc(size*ptr_size);
if (_vect->my_vector) {
return 0;
}
return 1;
}
Then:
Vector _vector;
char *a;
if (init_Vector(&_vector, 5, sizeof(char)) == 0) {
printf("Success!\n");
}
else {
printf("Failure!\n");
/* treat appropriately (return error code/exit) */
}
/* do whatever with a (if needed) and _vector*/