Using realloc in dynamic structure array - c

I am trying to use realloc to dynamically create instances of a struct, filling it with data from a temporary structure as I go. The program crashes when it reaches the line to malloc a pointer of the structure a second time but I am not sure how I should structure this function. I have the following code:
#define MAX_STRING 50
struct data {
int ref;
int port;
char data[MAX_STRING+1];
}valid, invalid;
void read_file(FILE *file);
void validate(struct data* temp);
int g = 0;
int main(){
char inputfile[100];
FILE *file = fopen("file.txt" , "r");
if (file != NULL){
read_file (file);
}
else{
// Some code here..
}
return 0;
}
void read_file(FILE *file){
struct data* temp = malloc(sizeof(struct data));
char buf[1024];
while(!feof(file)){
fgets(buf, sizeof buf, file))
sscanf(buffer, "%d.%d.%s", &temp->ref, &temp->port, &temp->data);
validate(temp);
g++;
}
}
void validate(struct data* temp){
if((some condition) && (some condition))
{
create_valid(temp);
}
if((some condition) && (some condition))
{
create_invalid(temp);
}
}
I am unsure of how to structure the following function:
int create_vaild(struct data* temp){
struct data* valid = malloc(sizeof(struct data)); <<<<<<<<< Line that crashes
valid = realloc(valid, g * sizeof(struct data));
valid[g] = *temp;
if (valid[g] == NULL){
//error.
};
printf("\n%i:%i:%s\n", (valid+g)->ref, (valid+g)->port, (valid+g)->data);
return 0;
}

I see one potential problem:
You have g set to 0 i.e.
int g =0;
You are not incrementing it before the call to create_valid(). You are using this value to allocate memory inside that functions:
valid = realloc(valid, g * sizeof(struct data));
So now g is 0.
Later in the next line you dereference this pointer
valid[g] = *temp;
This is some memory which you have not allocated as realloc() didn't allocate memory for you becasue you passed 0 to it.Hence the crash.

Related

Passing a struct to multiple other functions

I'm relatively new to programming and I am having some issues passing my struct to other functions. Here is what my actual code looks like:
typedef struct Memcheck {
char *memoryAdd;
char *file;
int line;
struct Memcheck_struct *next;
} Memcheck;
char *strdup2( char *str )
{
char *new;
new = malloc( strlen(str)+1 );
if (new)
strcpy( new, str );
return new;
}
/*Allocate memory for a ptr, and add it to the top of the linked list*/
void *memcheck_malloc(size_t size, char *file, int line){
Memcheck * new_memoryCheck = NULL;
Memcheck * head = NULL;
head = malloc(sizeof(Memcheck));
new_memoryCheck = malloc(sizeof(Memcheck));
new_memoryCheck->memoryAdd = malloc(sizeof(new_memoryCheck->memoryAdd));
new_memoryCheck->file = malloc(sizeof(new_memoryCheck->file));
new_memoryCheck->file = strdup2(file);
new_memoryCheck->line = line;
new_memoryCheck->next = head;
return new_memoryCheck;
}
/*Prints the error messages*/
void printList(Memcheck *new_memoryCheck) {
Memcheck * head = NULL;
Memcheck * current = head;
head = malloc(sizeof(Memcheck));
current = malloc(sizeof(Memcheck));
printf("new_mem file: %s\n", new_memoryCheck->file);
printf("current file: %s\n", current->file);
while (current != NULL) {
printf("in loop\n");
printf("memcheck error: memory address %p which was allocated in file \"%s\", line %d, was never freed\n", current, current->file, current->line);
current = current->next;
}
}
int memcheck_main(Memcheck new_memoryCheck){
printf("newmem file: %s\n", new_memoryCheck.file);
printf("Entering printList\n");
printList(&new_memoryCheck);
return 0;
}
I have strdup2 because apparently ansi doesn't have stdrup.
I know to use pass by reference to some degree but I'm not exactly sure where to use the * and & operators
Since it appears that you are writing a surrogate for malloc() that records which memory was allocated where, you probably need code similar to:
typedef struct Memcheck Memcheck;
struct Memcheck
{
void *data;
size_t size;
const char *file;
int line;
Memcheck *next;
};
static Memcheck *memcheck_list = 0;
/* Allocate memory and record the allocation in the linked list */
void *memcheck_malloc(size_t size, const char *file, int line)
{
Memcheck *node = malloc(sizeof(*node));
void *data = malloc(size);
if (node == 0 || data == 0)
{
free(node);
free(data);
return 0;
}
node->data = data;
node->size = size;
node->file = file;
node->line = line;
node->next = memcheck_list;
memcheck_list = node;
return data;
}
Note that if either (or both) memory allocations fails, the memory is all freed before returning. Using free() on a null (0) pointer is a no-op. Thus the clean-up is safe. The information can simply be copied into the structure as shown; no need for extra memory allocations for the file name, for example, as long as you pass __FILE__ to the function (which is a string literal, and therefore has a lifetime as long as the rest of the program).

Creating Dynamically Allocated Strings from a file in C

I am having some issues with dynamically allocating a string for a node in a tree. I have included my node structure below for reference.
struct node
{
char *string;
struct node *left;
struct node *right;
};
typedef struct node node;
I am supposed to read words from a text file and then store those words into a tree. I am able to store char arrays that have been defined, such as char string[20] without problems, but not strings that are supposed to be dynamically allocated.
I am only going to post the code I am using to read my file and try to create the dynamically allocated array. I have already created the file pointer and checked that it is not NULL. Every time I try to run the program, it simply crashes, do I need to try and read the words character by character?
//IN MAIN
node *p, *root ;
int i;
int u;
root = NULL;
char input[100];
while(fscanf(fp, "%s", &input) != EOF)
{
//Create the node to insert into the tree
p = (node *)malloc(sizeof(node));
p->left = p->right = NULL;
int p = strlen(input); //get the length of the read string
char *temp = (char*) malloc(sizeof(char)*p);
//malloc a dynamic string of only the length needed
strcpy(local, input);
strcpy(p->word,local);
insert(&root, p);
}
To be completely clear, I only want advice regarding the logic of my code, and only would like someone to help point me in the right direction.
You are invoking many undefined behaviors by
passing pointer to object having wrong type to scanf(). i.e. In fscanf(ifp, "%s", &input), char(*)[100] is passed where char* is expected
accessing out-of-range of allocated buffer when storeing terminating null-character in strcpy(local, input);
using value of buffer allocated via malloc() and not initialized in strcpy(curr->word,local);
Your code should be like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct node_t {
struct node_t* left, *right;
int count;
char* word;
} node;
void insert(node ** tree, node * item);
int main(void) {
FILE* ifp = stdin;
node * curr, * root;
int i;
int u;
root = NULL;
char input[100];
/* you should specify the maximum length to read in order to avoid buffer overrun */
while(fscanf(ifp, "%99s", input) != EOF)
{
//Create the node to insert into the tree
curr = malloc(sizeof(node));
if(curr == NULL) /* add error check */
{
perror("malloc 1");
return 1;
}
curr->left = curr->right = NULL;
curr->count = 1;
int p = strlen(input); //get the length of the read string
char *local = malloc(sizeof(char)*(p + 1)); /* make room for terminating null-character */
if (local == NULL) /* add error check again */
{
perror("malloc 2");
return 1;
}
//malloc a dynamic string of only the length needed
//To lowercase, so Job and job is considered the same word
/* using strlen() in loop condition is not a good idea.
* you have already calculated it, so use it. */
for(u = 0; u < p; u++)
{
/* cast to unsigned char in order to avoid undefined behavior
* for passing out-of-range value */
input[u] = tolower((unsigned char)input[u]);
}
strcpy(local, input);
curr->word = local; /* do not use strcpy, just assign */
insert(&root, curr);
}
/* code to free what is allocated will be here */
return 0;
}
//Separate insert function
void insert(node ** tree, node * item)
{
if(!(*tree))
{
*tree = item;
return;
}
if(strcmp(item->word,(*tree)->word) < 0)
insert(&(*tree)->left, item);
else if(strcmp(item->word,(*tree)->word) > 0)
insert(&(*tree)->right, item);
/* note: memory leak may occur if the word read is same as what is previously read */
}

Read/write linked nodes from binary file

I have a problem reading a binary file which contains linked nodes.
This is the code:
lib1.c
struct my_stack_node {
void *data;
struct my_stack_node *next;
};
struct my_stack {
int size;
struct my_stack_node *first;
};
int my_stack_write(struct my_stack *stack, char *filename){
int count = 0;
struct my_stack_node *aux;
FILE *file = fopen(filename, "wb");
if(stack->first != NULL){
aux = stack->first;
count++;
while(aux->next != NULL){
fwrite(&aux ,sizeof(aux), 1, file);
aux = aux->next;
count++;
}
}
fwrite(&stack, sizeof(stack), 1, file); //Escriure stack
fclose(file);
return count;
}
struct my_stack *my_stack_read(char *filename){
struct my_stack *stackRead;
struct my_stack_node *stackNode;
FILE *file = fopen(filename, "rb");
if(!file){
puts("Impossible obrir el fitxer");
return NULL;
}else{
int primerInici = 0;
while(!feof(file)){
if(primerInici == 0){
stackRead = (struct my_stack*) malloc(sizeof(struct my_stack));
fread(stackRead, sizeof(stackRead), 1, file);
primerInici = 1;
}else{
//Crear nou node i llegir-lo del fitxer
stackNode = (struct my_stack_node*) malloc(sizeof(struct my_stack_node));
fread(stackNode, sizeof(stackNode), 1, file);
//Afegir node a la pila
stackNode->next = stackRead->first;
stackRead->first = stackNode;
}
}
fclose(file);
return stackRead;
}
}
main.c
struct my_data {
int val;
char name[60];
};
int main() {
struct my_stack *s, *t, *u;
struct my_data *data, *data1, *data2;
//...more code
u = my_stack_read("/tmp/my_stack.data");
if (! u) {
puts("Error in my_stack_read (u)");
exit(1);
}
if (my_stack_len(s) != my_stack_len(u)) {
puts("Stacks s and u don't have the same len");
exit(1);
}
// Test we can free the data and compare stacks s and u
while((data1 = my_stack_pop(s))) {
data2 = my_stack_pop(u);
if (! data2 || data1->val != data2->val || my_strcmp(data1->name, data2->name)) {
printf("Data in s and u are not the same: %d <> %d\n", data1->val, data2->val);
exit(1);
}
free(data1);
free(data2);
}
//...more code
puts("All tests passed");
return 0;
}
The result of the execution is:
Stack len: 100
Data in s and u are not the same: 22145808 <> 22134800
The correct result should be:
All tests passed
Here lies the problem (inside my_stack_write) :
aux = stack->first;
count++;
while(aux->next != NULL){
fwrite(&aux ,sizeof(aux), 1, file);
aux = aux->next;
count++;
}
You are writting the pointer aux. Not the struct which is being pointed by aux. Neither the data pointed by data, which is the important part.
So. Imagine you have something like this :
my_stack { first=0x100 }
at memoryPosition 0x100 we have : my_stack_node { data=0x200; next=0x300 }
at memoryPosition 0x300 we have : my_stack_node { data=0x500; next=0x600 }
at memoryPosition 0x600 we have : my_stack_node { data=0x700; next=NULL }
For that structure your program is writting : 0x100, 0x300
You are writting the memory addresses of the nodes making up your linked list. And you are missing the last node, which is a different kind of error.
But that is useless. Next time you run your program your nodes may be in different memory addresses so there is no point in saving them. It is dynamic memory, it may reside at different places each time you run your program.
What you should be writting instead is the data your linked list is listing.
This same mistake is repeated in pretty much the whole program.
How to properly write the data contained in the linked list :
void writeStack(struct my_stack *stack, const char *filename)
{
struct my_stack_node *aux;
FILE *file = fopen(filename, "wb");
if ( file==NULL )
{
fprintf( stderr, "Could not open %s for writting.\n", filename );
exit(1);
}
if (stack != NULL)
{
aux = stack->first;
while(aux != NULL)
{
// aux->data is of type void*
// Assuming that aux->data contains a struct my_data
// Most likely it would be better to redefine data as having
// type struct my_data*
fwrite(aux->data ,sizeof(struct my_data), 1, file);
aux = aux->next;
}
}
fclose(file);
}
Here we traverse all the nodes in the list.
And for each we write the data in them contained.
Notice how fwrite( aux->data, writes the data pointed at by aux->data, which is correct.
While fwrite( &aux, would write the memory address contained at aux, which is unlikely to be correct.
And fwrite( &aux->data, would write the memory address contained at aux->data, which is also unlikely to be correct.
It is up to you to add code for counting and to write the reading function.
You only read and write the stack itself, not the payload of its nodes, which is stored voa a void * pointer.
The nodes themselves carry no meaningful information. Or information that is meaningful across sessions, rather: The data and next pointers are valid only in the session that writes the data.
Your stack is essentially a linear data structure. Instead of storing the nodes, store the stack data as array of data members. When you read them in, construct a list with freshly allocated nodes and the read data fields.
Your stack uses void * pointers to allow for various data types. You must therefore find a way to tell the read and write methods how the data should be written or read.
You could provide a callback function where you pass the opened file. Such callbacks could deal with complex data structures as payload, if needed.
Edit: The code below shows an example of how to serialise a stack with custom functions for reading and writng. The symmetric callbacks should write the data to the file and read the data. The read function can allocate memory, which is owned by the stack. The user must make sure to free it.
The callbacks can return a negative number to indicate an error. The stack to read need not be empty. Read data ist just pushed to the stack.
#include <stdlib.h>
#include <stdio.h>
#define die(...) exit((printf(__VA_ARGS__), putchar('\n'), 1));
typedef struct Stack Stack;
typedef struct SNode SNode;
struct SNode {
void *data;
SNode *next;
};
struct Stack {
SNode *head;
};
/*
* Core stack functions
*/
void stack_push(Stack *st, void *data)
{
SNode *sn = malloc(sizeof(*sn));
sn->data = data;
sn->next = st->head;
st->head = sn;
}
void *stack_pop(Stack *st)
{
void *data;
SNode *sn;
if (st->head == NULL) die("Undeflow");
sn = st->head;
data = sn->data;
st->head = sn->next;
free(sn);
return data;
}
int stack_empty(const Stack *st)
{
return (st->head == NULL);
}
/*
* Stack write function with custom callback
*/
int stack_write(const Stack *st, const char *filename,
int (*func)(FILE *f, const void *data))
{
const SNode *sn = st->head;
size_t count = 0;
FILE *f = fopen(filename, "wb");
if (f == NULL) return -1;
fwrite(&count, 1, sizeof(count), f);
while (sn) {
if (func(f, sn->data) < 0) {
fclose(f);
return -1;
}
count++;
sn = sn->next;
}
fseek(f, SEEK_SET, 0);
fwrite(&count, 1, sizeof(count), f);
fclose(f);
return count;
}
/*
* Stack read function with custom callback
*/
int stack_read(Stack *st, const char *filename,
int (*func)(FILE *f, void **data))
{
size_t count = 0;
size_t i;
FILE *f = fopen(filename, "rb");
if (f == NULL) return -1;
fread(&count, 1, sizeof(count), f);
for (i = 0; i < count; i++) {
void *p;
if (func(f, &p) < 0) {
fclose(f);
return -1;
}
stack_push(st, p);
}
fclose(f);
return count;
}
/*
* Custom data struct with read/write functions
*/
struct my_data {
int val;
char name[60];
};
int my_data_write(FILE *f, const void *data)
{
if (fwrite(data, sizeof(struct my_data), 1, f) < 1) return -1;
return 0;
}
int my_data_read(FILE *f, void **data)
{
*data = malloc(sizeof(struct my_data));
if (*data == NULL) return -1;
if (fread(*data, sizeof(struct my_data), 1, f) < 1) {
free(data);
return -1;
}
return 0;
}
/*
* Example client code
*/
int main()
{
Stack s = {NULL};
Stack t = {NULL};
struct my_data aa = {23, "Alice Atkinson"};
struct my_data bb = {37, "Bob Bates"};
struct my_data cc = {28, "Carol Clark"};
stack_push(&s, &aa);
stack_push(&s, &bb);
stack_push(&s, &cc);
stack_write(&s, "kk", my_data_write);
while (s.head) stack_pop(&s);
stack_read(&t, "kk", my_data_read);
while (t.head) {
struct my_data *p = stack_pop(&t);
printf("%4d '%s'\n", p->val, p->name);
free(p);
}
return 0;
}

Linked list won't print? C

So my assignment is to take in letters (6 per line) of a text file, save it into linked lists, and then print out the information of specific "die"(in this case) - which is each group of 6 letters.
I've got the data to read in correctly (I think) in the readData function, but am unsure if that linked list is getting passed correctly. When I try to print out the linked list in main (lines ~40-41) I get nothing. Am I passing my function incorrectly to readData?
Here's my code:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define LENGTH 80
struct boggleDataNode {
char data[3];
struct boggleDataNode *nextData;
};
struct boggleDieSideNode{
char dieSideData[3];
struct boggleDieSideNode *nextSide;
};
void readData(struct boggleDataNode *temp);
void printData(struct boggleDataNode *temp);
int main() {
int counter = 0;
struct boggleDataNode *head;
struct boggleDieSideNode *head1;
struct boggleDataNode *temp;
head = NULL;
head1 = NULL;
temp = head;
printf("test\n\n");
readData(&temp);
// printData(temp);
while(counter = 0, counter<100, counter++)
printf("%s ", temp->data[counter]);
system("pause");
return 0;
}
void readData(struct boggleDataNode *temp) {
//initializing variables including
//opening the input file
FILE *input = fopen("BoggleData.txt","r");
char data[96] = {};
struct boggleDataNode *new;
int counter = 0;
temp = new;
//error checking that the file opened
if (input == NULL) {
fprintf(stderr, "Can't open input file!\n");
exit(1);
}
new = (struct boggleDataNode *)malloc(sizeof(struct boggleDataNode));
while (fscanf(input, "%s", data) != EOF) {
printf("%s ", data);
strcpy(temp->data, data);
printf("Data number %d %s \n",counter,temp->data);
temp->nextData = NULL;
counter++;
}
}
You are passing your structure incorrectly to readData. Your declare your variable like so:
struct boggleDataNode *temp;
You invoke readData thusly:
readData(&temp);
You declare readData as such:
void readData(struct boggleDataNode *temp){
So, you declare both temp and readData's input as struct boggleDataNode *, but you pass &temp to readData. & means you are sending the address of what follows, so &temp is a pointer to a pointer to a struct boggleDataNode, which is a struct boggleDataNode **.
There are other problems with your code, but that is beyond the scope of your question. I will point out that your output loop is very, very wrong.

Returning structures from functions. C

I am new to C and programming as a whole. I am trying to create a simple file validation program that reads in records from a file and sorts valid from invalid records. I have managed to achieve this but have run into problems when trying to return the structs for use in the main program.
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#define MAX 20
typedef struct data{
int ref;
int serial;
char string[MAX+1];
}vaild,invalid;
int g = 1;
int e = 1;
void read(FILE *file);
void val(struct data* t);
void create_record(struct data* temp);
void create_error(struct data* temp);
void export_data(struct data* record, struct data* error);
int main(){
FILE *file = fopen("file.txt", "r");
if (file != NULL){
read (file);
I want to be able to call the structures 'valid and 'invalid' from here inside the main function. Like the commented out printf function below.
//printf("%i", valid[1].ref); <<<<<<<<<< I need to be able to play around with the structures from inside the main function!
}
return 0;
}
void read(FILE *file){
struct data* t = malloc(sizeof(struct data));
char buf[1000];
while(!feof(file)){
fgets(buf, sizeof buf, file);
sscanf(buf, "%d.%d.%s", &t->ref, &t->serial, t->string);
val(t);
}
}
void val (struct data* t){
if((t->ref < 30)){
struct data* valid = (struct data*) malloc(sizeof(struct data));
valid = (struct data*)realloc(valid, g * sizeof(struct data));
valid[g-1] = *t;
if (valid == NULL){
puts("Memory allocation error!");
exit(EXIT_FAILURE);
}
printf("\nGOOD:%i.%i.%s\n", valid[g-1].ref, valid[g-1].serial, valid[g-1].string);
g++;
}
else{
struct data* invalid = (struct data*) malloc(sizeof(struct data));
invalid = (struct data*)realloc(invalid, e * sizeof(struct data));
invalid[e-1] = *t;
if ( invalid == NULL){
puts("Memory allocation error!");
exit(EXIT_FAILURE);
}
printf("\nBAD:%i.%i.%s\n", invalid[e-1].ref, invalid[e-1].serial, invalid[e-1].string);
e++;
}
}
I cant seem to be able to call the structures from within main by using the return functions, I feel I must be doing something really simple wrong. Getting pretty frustrated.
The input file is like so:
04.06.hello
09.65.test
88.55.string
27.12.qwerty
11.53.ytrewq
92.02.ecco
Everything else is working fine and there are no compiler errors. I have changed all the return types to void to make it less messy, I think I must be using them wrong.
Found your problem
void val (struct data* t){
if((t->ref < 30)){
struct data* valid = (struct data*) malloc(sizeof(struct data));
valid = (struct data*)realloc(valid, g * sizeof(struct data));
valid[g-1] = *t;
if (valid == NULL){
puts("Memory allocation error!");
exit(EXIT_FAILURE);
}
printf("\nGOOD:%i.%i.%s\n", valid[g-1].ref, valid[g-1].serial, valid[g-1].string);
g++;
}
else{
struct data* invalid = (struct data*) malloc(sizeof(struct data));
invalid = (struct data*)realloc(invalid, e * sizeof(struct data));
invalid[e-1] = *t;
if ( invalid == NULL){
puts("Memory allocation error!");
exit(EXIT_FAILURE);
}
printf("\nBAD:%i.%i.%s\n", invalid[e-1].ref, invalid[e-1].serial, invalid[e-1].string);
e++;
}
}
In above code when you define valid and invalid inside If and else if , scope of these variables are inside those if conditions. So you will get "valid not defined" error.
Try this
struct data* val(struct data* t){
if((t->ref < 30)){
struct data* valid_file = (struct data*) malloc(sizeof(struct data));
valid_file = (struct data*)realloc(valid_file, g * sizeof(struct data));
valid_file[g-1] = *t;
if (valid_file == NULL){
puts("Memory allocation error!");
exit(EXIT_FAILURE);
}
printf("\nGOOD:%i.%i.%s\n", valid_file[g-1].ref, valid_file[g-1].serial, valid_file[g-1].string);
g++;
return valid_file;
}
// Will come when result is invalid
struct data* invalid_file = (struct data*) malloc(sizeof(struct data));
invalid_file = (struct data*)realloc(invalid_file, e * sizeof(struct data));
invalid_file[e-1] = *t;
if ( invalid_file == NULL){
puts("Memory allocation error!");
exit(EXIT_FAILURE);
}
printf("\nBAD:%i.%i.%s\n", invalid_file[e-1].ref, invalid_file[e-1].serial, invalid_file[e-1].string);
e++;
return invalid_file;
}
Note - Changed valid and invalid to different variable names to separate struct name definitions.
Complete working example :)
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#define MAX 20
typedef struct data{
int ref;
int serial;
char string[MAX+1];
}vaild,invalid;
int g = 1;
int e = 1;
struct data* read(FILE *file);
struct data* val(struct data* t);
void create_record(struct data* temp);
void create_error(struct data* temp);
void export_data(struct data* record, struct data* error);
int main(){
FILE *file = fopen("file.txt", "r");
if (file != NULL){
struct data* answ=read (file);
printf("%i \n", answ->ref);
}
return 0;
}
struct data* read(FILE *file){
struct data* t = malloc(sizeof(struct data));
char buf[1000];
while(!feof(file)){
fgets(buf, sizeof buf, file);
sscanf(buf, "%d.%d.%s", &t->ref, &t->serial, t->string);
val(t);
}
return t;
}
struct data* val(struct data* t){
if((t->ref < 30)){
struct data* valid_file = (struct data*) malloc(sizeof(struct data));
valid_file = (struct data*)realloc(valid_file, g * sizeof(struct data));
valid_file[g-1] = *t;
if (valid_file == NULL){
puts("Memory allocation error!");
exit(EXIT_FAILURE);
}
printf("\nGOOD:%i.%i.%s\n", valid_file[g-1].ref, valid_file[g-1].serial, valid_file[g-1].string);
g++;
return valid_file;
}
// Will come when result is invalid
struct data* invalid_file = (struct data*) malloc(sizeof(struct data));
invalid_file = (struct data*)realloc(invalid_file, e * sizeof(struct data));
invalid_file[e-1] = *t;
if ( invalid_file == NULL){
puts("Memory allocation error!");
exit(EXIT_FAILURE);
}
printf("\nBAD:%i.%i.%s\n", invalid_file[e-1].ref, invalid_file[e-1].serial, invalid_file[e-1].string);
e++;
return invalid_file;
}
Returning a struct in C is acceptable when the struct is small. Otherwise you'd be better off using pointers.
The snippet below is a simple example that shows you how to return a struct.
Same rules apply as returning any other data type (e.g., int, double, ...), return types need to match and the function needs to have a return statement.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int x;
int y;
} Point;
Point init_point(Point p, int x, int y) {
p.x = x;
p.y = y;
return p;
}
void main() {
Point p1, p2;
printf("%d, %d\n", p1.x, p1.y);
printf("%d, %d\n", p2.x, p2.y);
p1 = init_point(p1, 55, 10);
printf("%d, %d\n", p1.x, p1.y);
printf("%d, %d\n", p2.x, p2.y);
p2 = init_point(p2, 10000, 190);
printf("%d, %d\n", p1.x, p1.y);
printf("%d, %d\n", p2.x, p2.y);
}
The result is :
-1080464084, -1080464264
1, -1080464092
55, 10
1, -1080464092
55, 10
10000, 190

Resources