Segmentation Fault while trying to fill a list [duplicate] - c

Suppose I have the following struct and function returning a pointer:
typedef struct {
int num;
void *nums;
int size;
} Mystruct;
Mystruct *mystruct(int num, int size)
{
//Is the following correct? Is there a more efficient way?
Mystruct mystruct;
mystruct.num = num;
mystruct.size = size;
mystruct.nums = malloc(num*sizeof(size));
Mystruct *my;
*my = mystruct;
return my;
}
I want to define any Mystruct pointer using the above function. Should I declare a Mystruct variable, define the properties of Mystruct, assign a pointer to it, and return the pointer or define the properties of a mystruct property through a pointer immediately?

Should I declare a Mystruct variable,
define the properties of Mystruct,
assign a pointer to it, and return the
pointer
Definitely not, because the variable defined in the function (in "auto" storage class) will disappear as the function exits, and you'll return a dangling pointer.
You could accept a pointer to a Mystruct (caller's responsibility to allocate that) and fill it in; or, you can use malloc to create a new one (caller's responsibility to free it when it's done). The second option at least lets you keep the function signature you seem to be keen on:
Mystruct *mystruct(int num, int size)
{
Mystruct *p = malloc(sizeof(MyStruct));
....
return p;
}
but it's often an inferior one -- since the caller has to have responsibilities anyway, may as well go with the first option and potentially gain performance (if the caller can use an auto-class instance because it knows the scope of use is bounded).

You can't use the variable because it will be deallocated when the function exits. For example:
Mystruct *mystruct(int num, int size)
{
MyStruct x;
x.num = 1;
...
return &x;
}
Will give a segmentation fault or access violation because the memory for x is deallocated as soon as you exit. So you have to allocate memory for the struct (and be sure to free it up later) or declare a global that will stay around for ever. Example for the latter...
Mystruct *mystruct(int num, int size)
{
MyStruct *x;
x = (MyStruct*)malloc( sizeof( MyStruct ) );
x->num = 1;
...
return x;
}

If you are writing generic code and you don't know how it may be used, it's good to provide both options:
int mystructm(Mystruct *storage, int num, int size)
{
int rv = 0;
storage->num = num;
storage->size = size;
storage->nums = malloc(num*sizeof(size));
if (!storage->nums)
return -1;
return 0;
}
Mystruct *mystruct(int num, int size)
{
Mystruct *mp = (Mystruct *)malloc(sizeof(Mystruct));
if (mp)
{
if (mystructm(mp, num, size) == -1)
{
free(mp);
mp = NULL;
}
}
return mp;
}
The idea is that as a library writer, you shouldn't dictate policy (such as that each Mystruct must be dynamically allocated) but should let the application writer decide that.

It's important to remember that the pointer is not something you assign to the structure, but rather the pointer indicates the location in memory that you wish to treat as a structure. Based on your question, you really want to allocate the memory to hold the data structure. This gives you a pointer to the memory location allocated. Once you have that, you can return it.
EDIT (after edit to original question)
Looking at your edit to the question, you definitely will have problems with the "my" pointer. This is uninitialised, and may point to anywhere in memory. When you attempt to copy the structure to it, you'll probably get a seg-fault.

Allocating a new Mystruct and returning a pointer to it would usually look more or less like this:
Mystruct *mystruct(int num, int size)
{
Mystruct *result;
result = malloc(sizeof(MyStruct));
if (!result)
return NULL;
result->num = num;
...
return result;
}
Later, when you are done with the Mystruct allocated here with malloc, it should be freed again with free().
Just declaring a local variable and returning a pointer to that local variable will not work. The local variable goes out of scope at the end of the function and the memory where it was stored is most likely reused for other purposes. The returned pointer will still point to the memory location where the local variable once was, but since that variable doesn't exist anymore, that pointer wouldn't be of much use.

One more way to do it..
int mystruct(Mystruct *mystruct, int num, int size){
if(mystruct == NULL)
return -1;
mystruct->num = num;
mystruct->size = size;
::
return 0;
}
int main(){
Mystruct my;
if(mystruct(&my, 3, 4) != 0){
fprintf(stderr, "Cannot init!\n");
exit(0);
}
::
}

Related

How can I return different address of structs?

I have a array of structs in the main function and I would like to save data of few structs. I'm using a function that receive the wanted data and put it into struct that is defined into the function.
At the end of the process I return the address of this struct.
But if I call to this function few times ,it always defines the same address of the struct so I am losing a data of the previous call.
#include<stdio.h>
struct data {
int day;
};
struct data* Dates(int val);
int main() {
struct data* Dates1[3];
int array[] = { 12, 15, 2021 };
for (int i = 0; i < 3; i++) {
Dates1[i] = Dates(array[i]);
}
}
struct data* Dates(int val) {
struct data Date;
Date.day = val;
return &Date; ///AFTER EVERY CALL TO THIS FUNCTION IT RETURN THE SAME ADDRESS!!!
}
When you call a function, it creates a stack frame. Local variables to that function are allocated within that stack frame. When the function exits, the stack frame is "destroyed". That memory can be reused.
You're seeing this behavior because each time you call the function in your loop, it reuses the same memory space.
You cannot rely on the validity of an address to a variable allocated on the stack outside of the current function call. If you need a value to live on after the function call, you need to dynamically allocate it - typically with malloc. Just don't forget to free that memory when you're done with it.
You have to write you function as something like this:
struct data* Date = (struct data*) malloc(sizeof(struct data))
Date->day = val;
return Date;
Afterwards you have to call free() on the pointer when it is no longer used. (if not this is called a memory leak)
When you are confused keep in mind the simple rule that you can only return pointers up to that call level where the variable pointing too was created.
If you want to learn why this is, you should read up on what a call stack is and how stack variables work.
If you don't want to use malloc, an alternative is have the function take in a pointer to the uninitialized value, void Dates(struct data *, int);, then the caller is responsible for the memory.
#include <stdio.h>
#include <assert.h>
struct data {
int day;
};
static void Dates(struct data *const data, const int val) {
assert(data); /* Defensive debug. */
data->day = val;
}
int main(void) {
int array[] = { 12, 15, 2021 };
struct data dates1[sizeof array / sizeof *array];
for(int i = 0; i < sizeof dates1 / sizeof *dates1; i++)
{
Dates(dates1 + i, array[i]);
printf("%d: %d\n", i, dates1[i].day);
}
}
This can be better suited for when one wants a memory-allocation-agnostic function; in this example, I've reserved memory on the heap instead of dynamically.

Can I iterate dynamic array without knowing the size of it

I allocated some data in a dynamic array of a struct. Can I iterate that struct * without knowing it's size somehow?
Would this work?
int main() {
struct *foo = NULL;
//struct filling
iterate_foo(foo);
}
void iterate_foo(struct *foo) {
int i=0;
while (foo[i] != NULL) { // Would this work?
//something
}
}
The only way that can work is if you have a sentinel value in the array that indicates the end. Strings in C work that way.
For instance, if you invoke strcpy(a, b), then characters from b will be copied to a until and including the value zero. If there's no zero terminator within the b array, or if a is not big enough to hold all the characters, the function call leads to undefined behavior.
If you don't want to use a sentinel value, you have the option of passing the size as a separate parameter. Another way is to wrap things in a container struct, like this:
struct container {
struct mystruct *data;
size_t size;
}
Furthermore, struct *foo = NULL; is wrong. It has to be something like struct mystruct *foo = NULL;
But if you have this code:
void foo(T *ptr) {
// Do something
}
int main(void) {
T *a = malloc(N * sizeof *a);
T b[N];
foo(a);
foo(b);
}
Then it's completely impossible for foo to figure out N in a portable way. In some cases, believe that the implementation of malloc stores the size right before the data. But don't try to exploit that. It will only cause severe head ache.

Initialize an empty nested struct using a function

I have to initialize tCoworking coworking by implementing init_coworking function that is declared at the end.
/* Constants *********************************************************/
#define nWorkSpaces 50
#define unlimited 2000
/* Types *************************************************************/
typedef enum {tableFlex, tableFix, officeFix} rate;
typedef char string[55];
typedef struct {
int reservationId;
float monthPayment;
} tContractAnnex;
typedef struct {
int id;
string name;
int discount;
} tPartner;
typedef struct {
int id;
float surface;
rate rateType;
} tWorkspace;
typedef struct {
int partnerId;
int month;
int year;
tContractAnnex annex;
} tContract;
typedef struct {
tWorkspace workSpace[nWorkSpaces];
tContract contract[unlimited];
tPartner partner[unlimited];
} tCoworking;
/* Function declaration */
void init_coworking(tCoworking *coworking);
As you can see the problem I have is that tCoworking is a nested struct with array of stucts as data types..
So far I'm doing this in order to initialize it but it must be a better way to do it.
void init_coworking(tCoworking *coworking){
coworking = malloc(sizeof(tCoworking));
coworking->partner[0].id = 0;
coworking->partner[0].discount = 0;
strcpy(coworking->partner[0].name, "");
coworking->workSpace[0].id = 0;
coworking->workSpace[0].rateType = 0;
coworking->workSpace[0].surface = 0;
coworking->contract[0].partnerId = 0;
coworking->contract[0].year = 0;
coworking->contract[0].month = 0;
coworking->contract[0].annex.monthPayment = 0;
coworking->contract[0].annex.reservationId = 0;
}
void init_coworking(tCoworking *coworking) {
coworking && memset( coworking, 0, sizeof( tCoworking ) );
}
memset initializes a block of memory - of specifiable length - to a single byte value. Your example indicates that you desire zero-initialization of the entire object, so memset serves this purpose well.
NULL-check your input argument.
I recommend you not malloc or calloc in your function because your function signature implies that the caller is the owner of the tCoworking. If you malloc within your init_coworking() function, then you'll have created a new heap-allocated instance of a tCoworking with no clear ownership. You can try keep track of newly-allocated objects in some type of container, but that's going far beyond the scope of your question -- keep it simple.
The simplest way is to use calloc. Like malloc it allocates memory for you but it also sets all the memory to zero.
However - more important is that your current function doesn't make sense. The memory you allocate is simply lost. The caller of init_coworking will never get the allocated and initialized memory.
Either you should:
Not do any malloc(or calloc)
or
Return the malloced pointer.
Since the prototype suggest that you get a tCoworking pointer, the most likely thing is that it's already allocated (in some way), i.e. you want option 1.
So just do:
void init_coworking(tCoworking *coworking){ // NO malloc
memset(coworking, 0, sizeof(tCoworking));
}
In case you only want the first array member set to zero (like your code indicates) you may get a little performance improvement by:
void init_coworking(tCoworking *coworking){ // NO malloc
memset(&coworking->partner[0], 0, sizeof(coworking->partner[0]));
... similar for the other arrays ...
}
but I doubt that's worth the trouble...

Creating an Instance of a struct

I have this struct
struct FluxCapacitor{
unsigned char* c_string;
unsigned int value;
};
Now I need to create an instance of this struct. I googled this problem and found that I have to use something like this
typedef struct FluxCapacitor{
unsigned char* c_string
unsigned int value;
};
But I dont really understand the next step with malloc(). Can someone explain it to me?
You do not need malloc() to create an instance of a struct. And I would recommend that you avoid typedefing structures merely to reduce keystrokes. The extra keystrokes would only be saved in declarations and function prototypes (and maybe if you need to cast something), since you don't need the struct keyword elsewhere; the advantage is that when you see struct FluxCapacitor, you know exactly what it is. If you only see FluxCapacitor alone, you don't know if it is a typedef for a struct, or a union, or an integer type or what.
Note that the posted code was missing the semicolon at the end of the declaration. Also, it is unclear why you have unsigned char* c_string;. This may not allow assignment to a string literal. I have changed this in the code below. You can create a single struct like this:
struct FluxCapacitor
{
char *c_string;
unsigned int value;
};
...
struct FluxCapacitor fcap_1;
You can then assign values to the fields of fcap_1:
fcap_1.c_string = "McFly";
fcap_1.value = 42;
Note that you could also use designated initializers at the point of declaration:
struct FluxCapacitor fcap_2 = { .c_string = "Biff",
.value = 1985
};
If you need an array of FluxCapacitor structures, just declare one:
struct FluxCapacitor fcaps[2];
You can assign to the fields of each array member in a loop:
struct FluxCapacitor fcaps[2];
char *somestrings[] = { "McFly", "Biff" };
unsigned somevalues[] = { 42, 1985 };
for (size_t i = 0; i < 2; i++) {
fcaps[i].c_string = somestrings[i];
fcaps[i].value = somevalues[i];
}
Alternatively, you can use designated initializers here too:
struct FluxCapacitor fcaps[2] = { { .c_string = "McFly", .value = 42 },
{ .c_string = "Biff", .value = 1985}
};
Using malloc()
Since OP seems determined to use malloc(), it would be good to first recall that memory allocated with malloc() must later be deallocated with free(). Also note that malloc() can fail to allocate memory, returning a null pointer. Thus the result of a call to malloc() must be checked before attempting to dereference this pointer. The additional complexity should be avoided in favor of the above approaches unless OP has good reason to do manual allocation.
In the code below, the function create_flux_cap() takes a string and an unsigned int as arguments, and returns a pointer to a newly allocated FluxCapacitor structure with the arguments assigned to the appropriate fields. Note that since the FluxCapacitor structure is accessed through a pointer, the arrow operator is used instead of the dot operator.
Inside the function, the return value from the call to malloc() is checked before attempting assignment. If the allocation has failed, no assignment is made and a null pointer is returned to the calling function. Note that in the call to malloc(), the result is not cast, since there is no need for this in C and it needlessly clutters the code. Also observe that an identifier is used instead of an explicit type with the sizeof operator. This is less error-prone, easier to maintain if types change in the future, and is much cleaner code. That is, instead of this:
new_fcap = (struct FluxCapacitor *)malloc(sizeof (struct FluxCapacitor));
use this:
new_fcap = malloc(sizeof *new_fcap);
In main(), the return values from the calls to create_flux_cap() are checked. If an allocation has failed, the program exits with an error message.
The stdlib.h header file has been included for the function prototypes of malloc() and exit(), and also for the macro EXIT_FAILURE.
#include <stdio.h>
#include <stdlib.h>
struct FluxCapacitor
{
char* c_string;
unsigned value;
};
struct FluxCapacitor * create_flux_cap(char *, unsigned);
int main(void)
{
struct FluxCapacitor *fcap_1 = create_flux_cap("McFly", 42);
struct FluxCapacitor *fcap_2 = create_flux_cap("Biff", 1985);
/* Check for allocation errors */
if (fcap_1 == NULL || fcap_2 == NULL) {
fprintf(stderr, "Unable to create FluxCapacitor\n");
exit(EXIT_FAILURE);
}
/* Display contents of structures */
printf("%s, %u\n", fcap_1->c_string, fcap_1->value);
printf("%s, %u\n", fcap_2->c_string, fcap_2->value);
/* Free allocated memory */
free(fcap_1);
free(fcap_2);
return 0;
}
struct FluxCapacitor * create_flux_cap(char *str, unsigned val)
{
struct FluxCapacitor *new_fcap;
new_fcap = malloc(sizeof *new_fcap);
if (new_fcap != NULL) {
new_fcap->c_string = str;
new_fcap->value = val;
}
return new_fcap;
}
You need malloc for dynamic allocation of memory.In your case, both the types char and int are known to the compiler, it means the compiler can know the exact memory requirement at compile time.
For e.g. you can create a struct object like in the main function
#include<stdio.h>
#include<stdlib.h>
struct FluxCapacitor{
unsigned char* c_string;
unsigned int value;
};
int main() {
FluxCapacitor x;
x.c_string = "This is x capacitor"
x.value = 10
}
The x is of value type. You can make a copy and pass around this value. Also, observe we are using . notation to access its member variables.
But this doesn't happen at all time. We are not aware of future FluxCapacitor requirement and so above program will need more memory as while it is running and by using the malloc we can ask the compiler to provide us requested memory. This is a good place to use malloc, what malloc does is, it returns us a pointer to a piece of memory of the requested size. It is dynamic memory allocation.
Here's a simple example: let suppose if you need struct declaration of FluxCapacitor but don't know how many you will need, then use malloc
#include<stdio.h>
#include<stdlib.h>
typedef struct FluxCapacitor {
unsigned char* c_string;
int value;;
} flux;
// typedef is used to have the alias for the struct FluxCapacitor as flux
int main() {
flux *a = malloc(sizeof(flux)); // piece of memory requested
a -> c_string = "Hello World"; // Pointer notation
a -> value = 5;
free(a); // you need to handle freeing of memory
return 0;
}
.

Returning a struct pointer

Suppose I have the following struct and function returning a pointer:
typedef struct {
int num;
void *nums;
int size;
} Mystruct;
Mystruct *mystruct(int num, int size)
{
//Is the following correct? Is there a more efficient way?
Mystruct mystruct;
mystruct.num = num;
mystruct.size = size;
mystruct.nums = malloc(num*sizeof(size));
Mystruct *my;
*my = mystruct;
return my;
}
I want to define any Mystruct pointer using the above function. Should I declare a Mystruct variable, define the properties of Mystruct, assign a pointer to it, and return the pointer or define the properties of a mystruct property through a pointer immediately?
Should I declare a Mystruct variable,
define the properties of Mystruct,
assign a pointer to it, and return the
pointer
Definitely not, because the variable defined in the function (in "auto" storage class) will disappear as the function exits, and you'll return a dangling pointer.
You could accept a pointer to a Mystruct (caller's responsibility to allocate that) and fill it in; or, you can use malloc to create a new one (caller's responsibility to free it when it's done). The second option at least lets you keep the function signature you seem to be keen on:
Mystruct *mystruct(int num, int size)
{
Mystruct *p = malloc(sizeof(MyStruct));
....
return p;
}
but it's often an inferior one -- since the caller has to have responsibilities anyway, may as well go with the first option and potentially gain performance (if the caller can use an auto-class instance because it knows the scope of use is bounded).
You can't use the variable because it will be deallocated when the function exits. For example:
Mystruct *mystruct(int num, int size)
{
MyStruct x;
x.num = 1;
...
return &x;
}
Will give a segmentation fault or access violation because the memory for x is deallocated as soon as you exit. So you have to allocate memory for the struct (and be sure to free it up later) or declare a global that will stay around for ever. Example for the latter...
Mystruct *mystruct(int num, int size)
{
MyStruct *x;
x = (MyStruct*)malloc( sizeof( MyStruct ) );
x->num = 1;
...
return x;
}
If you are writing generic code and you don't know how it may be used, it's good to provide both options:
int mystructm(Mystruct *storage, int num, int size)
{
int rv = 0;
storage->num = num;
storage->size = size;
storage->nums = malloc(num*sizeof(size));
if (!storage->nums)
return -1;
return 0;
}
Mystruct *mystruct(int num, int size)
{
Mystruct *mp = (Mystruct *)malloc(sizeof(Mystruct));
if (mp)
{
if (mystructm(mp, num, size) == -1)
{
free(mp);
mp = NULL;
}
}
return mp;
}
The idea is that as a library writer, you shouldn't dictate policy (such as that each Mystruct must be dynamically allocated) but should let the application writer decide that.
It's important to remember that the pointer is not something you assign to the structure, but rather the pointer indicates the location in memory that you wish to treat as a structure. Based on your question, you really want to allocate the memory to hold the data structure. This gives you a pointer to the memory location allocated. Once you have that, you can return it.
EDIT (after edit to original question)
Looking at your edit to the question, you definitely will have problems with the "my" pointer. This is uninitialised, and may point to anywhere in memory. When you attempt to copy the structure to it, you'll probably get a seg-fault.
Allocating a new Mystruct and returning a pointer to it would usually look more or less like this:
Mystruct *mystruct(int num, int size)
{
Mystruct *result;
result = malloc(sizeof(MyStruct));
if (!result)
return NULL;
result->num = num;
...
return result;
}
Later, when you are done with the Mystruct allocated here with malloc, it should be freed again with free().
Just declaring a local variable and returning a pointer to that local variable will not work. The local variable goes out of scope at the end of the function and the memory where it was stored is most likely reused for other purposes. The returned pointer will still point to the memory location where the local variable once was, but since that variable doesn't exist anymore, that pointer wouldn't be of much use.
One more way to do it..
int mystruct(Mystruct *mystruct, int num, int size){
if(mystruct == NULL)
return -1;
mystruct->num = num;
mystruct->size = size;
::
return 0;
}
int main(){
Mystruct my;
if(mystruct(&my, 3, 4) != 0){
fprintf(stderr, "Cannot init!\n");
exit(0);
}
::
}

Resources