Cannot pass struct to function by reference [duplicate] - c

This question already has answers here:
Allocate struct from function in C
(4 answers)
C struct pointer - how to return struct pointer from module?
(1 answer)
Closed 3 years ago.
I'm creating a very simple dictionary structure in C and I'm not able to properly pass it to dictAdd function by reference. Something goes wrong inside the function and structure values get corrupted. See screenshots below. Everything is fine when I step into line 18, but when I get inside the function to line 19 the structure fields being to show inappropriate values.
Line 18
Line 19
Dictionary.h
typedef struct DictionaryStruct
{
int *arr;
int arrLen;
} Dictionary;
Dictionary *dictCreate(int arrLen);
int dictAdd(Dictionary *dict, char *key, char *val);
Dictionary.c
#include "Utils.h"
#include "Dictionary.h"
Dictionary *dictCreate(int arrLen)
{
int *arr = createIntArray(arrLen);
for (int i = 0; i < arrLen; ++i)
{
arr[i] = '\0';
}
Dictionary dict;
dict.arr = arr;
dict.arrLen = arrLen;
return &dict;
}
int dictAdd(Dictionary *dict, char *key, char *val) {
int hash = getHash(key, dict->arrLen);
dict->arr[hash] = val;
}
Main.c
#include <stdio.h>
#include <stdlib.h>
#include "Utils.h"
#include "Dictionary.h"
int main() {
Dictionary *dictPtr = dictCreate(5);
dictAdd(dictPtr, "key1", "Hello");
char *value1 = dictGet(dictPtr, "key1");
printf("%s", value1);
printf("Press any key to exit\n");
getchar();
}

You're returning a pointer to a local. Dereferencing a pointer after the end of its target's lifetime is undefined behavior.
Your dictCreate should heap-allocate the Dictionary structure as well (in addition to heap-allocating the int array).

Related

Setting value to struct pointers [duplicate]

This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed 2 years ago.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char** thingSize;
} Thing;
typedef struct {
Thing* thing;
} Game;
void load_array(Thing* thing) {
int i, j;
char **emptyThing = malloc(sizeof(char**));
emptyThing = malloc(sizeof(char*)*9);
for(i=0; i<9; i++) {
emptyThing[i] = malloc(sizeof(char)*9);
}
thing -> thingSize = emptyThing;
free(emptyThing);
}
int main(int argc, char* argv[]) {
Game* game;
load_array(game -> thing);
printf("HI");
}
I am getting a segmentation fault, I have found that the problem line is.
thing -> thingSize = emptyThing;
I am trying to set thingSize to be a 2d array equal to emptyThing.
As Fredrik said, the game pointer is not initialized to anything. It hold a garbage value, when dereferencing it, you will get a segfault.

problem in memory allocation to struct variable [duplicate]

This question already has answers here:
How do I modify a pointer that has been passed into a function in C?
(7 answers)
Closed 2 years ago.
Below is minimal, reproducible code for my problem. I don't know why this piece of code prints 1 as I expect to print 512.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct ser_buff_ {
#define SERIALIZE_BUFFER_DEFAULT_SIZE 512
void *b;
int size;
int next;
}ser_buff_t;
void
init_serialized_buffer(ser_buff_t *b){
b = (ser_buff_t*)calloc(1, sizeof(ser_buff_t));
b->b = calloc(1, SERIALIZE_BUFFER_DEFAULT_SIZE);
b->size = SERIALIZE_BUFFER_DEFAULT_SIZE;
b->next = 0;
}
int main(void){
ser_buff_t *b;
init_serialized_buffer(b);
printf("%d\n", b->size);
return 0;
}
#UnholySheep is right. You need to pass the reference to the first pointer in the init_serialized_buffer() in order to be able to modify it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct ser_buff_ {
#define SERIALIZE_BUFFER_DEFAULT_SIZE 512
void *b;
int size;
int next;
}ser_buff_t;
void
init_serialized_buffer(ser_buff_t **b){
*b = (ser_buff_t*)calloc(1, sizeof(ser_buff_t));
(*b)->b = calloc(1, SERIALIZE_BUFFER_DEFAULT_SIZE);
(*b)->size = SERIALIZE_BUFFER_DEFAULT_SIZE;
(*b)->next = 0;
}
int main(void){
ser_buff_t *b;
init_serialized_buffer(&b);
printf("%d\n", b->size);
return 0;
}

Realloc keeps returning NULL if reallocating structs [duplicate]

This question already has answers here:
Assignment of function parameter has no effect outside the function
(2 answers)
How do I modify a pointer that has been passed into a function in C?
(7 answers)
Closed 2 years ago.
Don't mind my code writing style. I specifically created this for testing purposes...
Now to the problem:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define EMB 31
#define NAME_MAX 50
struct TRIP {
char TRIP_NAME[EMB];
int TRIP_TIME;
};
struct DATE {
int day;
int month;
int year;
};
struct TRIP_INFORMATION {
char TRIP_NUMBER[EMB];
char EMBARKATION_POINT[EMB];
char SPECIFIC_DROPOFFPOINT[EMB];
char EXIT_DROPOFFPOINT[EMB];
struct DATE TRIP_DATE;
struct TRIP SPECIFIC_TRIP;
};
struct EMBARKATION_CARD{
//struct DATE TRIP_DATE;
char NAME[NAME_MAX];
int ID_NUMBER;
int PRIORITY_NUMBER;
//int TRIP_TIME;
//char EMBARKATION_POINT[EMB];
//char DROPOFFPOINT[EMB];
struct TRIP_INFORMATION TRIP_INFORMATION;
};
This is for the reference of declaration.
int BeginEmbarkationProcess(int *PASSENGER_COUNT, struct EMBARKATION_CARD * PASSENGER_TO_SAVE, int curr_day, int curr_month, int curr_year){
//struct EMBARKATION_CARD * P;
if(*PASSENGER_COUNT>1){
PASSENGER_TO_SAVE = realloc(PASSENGER_TO_SAVE, *PASSENGER_COUNT * sizeof(struct EMBARKATION_CARD));
if(PASSENGER_TO_SAVE == NULL){
puts("PASSENGER_TO_SAVE VARIABLE = HAS NOT ALLOCATED MEMORY");
return -1;
}
}
if(PASSENGER_TO_SAVE==NULL){
puts("PASSENGER TO SAVE POINTER HAS UNABLE TO ALLOCATE MEMORY");
return -1;
}
int x = 0;
for(x=0;x<*PASSENGER_COUNT;x++){
((PASSENGER_TO_SAVE+x))->ID_NUMBER = (x+1)*30;
((PASSENGER_TO_SAVE+x))->PRIORITY_NUMBER = (x+1)*17;
}
for(x=0;x<*PASSENGER_COUNT;x++){
printf("%d %d\n", (PASSENGER_TO_SAVE+x)->ID_NUMBER , (PASSENGER_TO_SAVE+x)->PRIORITY_NUMBER);
}
*PASSENGER_COUNT = *PASSENGER_COUNT + 1;
int r;
printf("ENTER -1 TO TERMINATE THIS LOOP\n");
scanf("%d", &r);
return r;
}
int main(){
//doIt();
struct EMBARKATION_CARD* E = malloc(sizeof(struct EMBARKATION_CARD));
int ct = 1;
int s = BeginEmbarkationProcess(&ct, E, 3, 3, 2020);
while(s!=-1){
s = BeginEmbarkationProcess(&ct, E, 3, 3, 2020);
}
return s;
}
Since I copy pasted this (and removed some commented out lines but eventually got tired of it), this copy pasted code might have some syntax error. Ignore those syntax error please.
The issue is that realloc WILL keep returning NULL.
This prevents me from readjusting it.
Can someone tell me what the hell is going on.
I know I may have made some errors here but I want to learn about it.
Yes I am just a student learning C language.

How do I correctly find out, what size the array of structs is? [duplicate]

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 5 years ago.
I have the following minimal example and I don't get, why my struct sizes are wrong. I'm expecting the output to be 50, instead I get 1. What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
typedef struct prod {
char *x;
} prod_t;
typedef struct obj {
prod_t *things;
} obj_t;
#define LARGE_BUF 100
#define CHAR_BUF 20
obj_t *func1(obj_t *t) {
t->things = malloc(sizeof(prod_t) * LARGE_BUF);
for (uint16_t i = 0; i < 50; i++) {
t->things[i].x = malloc(sizeof(char) * CHAR_BUF);
t->things[i].x = "hello";
}
return t;
}
int main(int argc, char **argv) {
obj_t *var = malloc(sizeof(obj_t));
var = func1(var);
printf("%lu\n", sizeof(var->things)/sizeof(var->things[0]));
return 0;
}
Since I don't have the number of entries, the function generated for me (it's 50 now, but it could change dynamically), how do I free(..) this up?
Is the only option to introduce a field in the struct, to keep track of the actual array size?
Yes you will need to add another member to the struct. For example a string wrapper type keeps track of the number of characters in it:
typdef struct {
char *base;
size_t n;
} string;
Notice n is of size_t, not int.

dereferencing pointer to incomplete type abstract-data-type [duplicate]

This question already has an answer here:
ERROR Dereferencing pointer to incomplete type in c [duplicate]
(1 answer)
Closed 7 years ago.
I have the following code parts:
dictionary.h
#ifndef _DICTIONARY_H
#define _DICTIONARY_H
typedef struct _dict_t dict_t;
typedef dict_t *Dictionary;
Dictionary dict_new(void);
(...)
dictionary.c
#include "dictionary.h"
struct _dict_t {
unsigned int size;
char **data;
};
Dictionary dict_new(void){
Dictionary dict = NULL;
dict = calloc(1, sizeof(struct _dict_t));
dict->data = calloc(1, sizeof(char));
dict->size = 0;
return (dict);
}
main.c
#include "dictionary.h"
Dictionary main_dict; // global dictionary
Dictionary ignored; // Yes, i know its horrible
int is_known(char *word){
int i;
for (i = 0; i < main_dict->size; ++i) {
if (strcmp(main_dict->data[i], word) == 0)
return 1;
}
for (i = 0; i < ignored->size; ++i){
if (strcmp(ignored->data[i], word) == 0)
return 1;
}
return 0;
}
int main(){
(...)
}
One of many errors (dereferencing pointer to incomplete type) is here:
main_dict->size
I can't find the error. What is happening?
When the type is incomplete, the compiler does not know what is inside an instance of that type. You need to provide definition of the type before you can dereference it.

Resources