From what I know, if you create a global struct as follows:
something name;
int main(){
}
You are able to access every field of the struct something, but if I were to instead make it as:
something* name;
int main(){
}
Would this now be incorrect because I have to malloc the size of the struct?
Note, I haven't decided what the struct something contains, this is more of a general question.
Basically, pointer is just a variable that points to some address in memory. So after
something* name;
int main(){
}
all you have is a pointer. It should point to a place in memory, where struct
something exists, but for now its just garbage there (notice that pointer can point to random location and as long as you don't try to do something with it no error will occur). After calling malloc system will reserve space needed for something and return pointer you should assign to global variable.
Would this now be incorrect because I have to malloc the size of the struct?
Well, it depends on how you are going to use it.
Code like:
something* name;
int main(){
}
is by it self perfectly valid C code.
You can for instance use it like:
something* name;
int main(){
something x = {....};
name = &x; // Make name point to a "something" object
...
name->some_member = ...;
...
}
or like
something* name;
int main(){
something x = {....};
name = malloc(sizeof *name); // Make name point to a "something" object
assert(name != NULL);
...
name->some_member = ...;
...
}
But without an assignment to name like name = ... you can't dereference the pointer. In other words, this would be invalid
something* name;
int main(){
...
name->some_member = ...; // INVALID
...
}
because name doesn't point to a "something" object.
BTW:
Since name is global the code
something* name;
is the same as
something* name = NULL;
UNRELATED:
There are cases where global variables are good and useful but in most cases, it's best to avoid globals.
Related
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;
}
.
I am new to use C programming and trying to fill a structure and print the actual data stored in my struct. I'm stuck with segfault. see my sample code:
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stddef.h>
struct full_data
{
char *first_name;
char *last_name;
int *id_code;
};
struct owner
{
int *owner_code;
struct full_data tdata;
};
void display_my_output(struct owner *mydata)
{
printf("My data should be: \nfirst_name: %s\nlast_name: %s\nid_code: %d\nowner_id: %d\n",mydata->tdata.first_name ,mydata->tdata.last_name,mydata->tdata.id_code,mydata->owner_code);
}
int main()
{
int i;
struct owner *own;
for(i=0 ; i<4 ; i++)
{
if(i==0)
{
own->tdata.first_name = "PAUL";
}
if(i==1)
{
own->tdata.last_name = "ROOT";
}
if(i==2)
{
own->tdata.id_code =30001;
}
if(i==3)
{
own->owner_code = 2*i;
}
}
display_my_output(own);
return 0;
}
Am expecting my out put as:
My data should be:
first_name: PAUL
last_name: ROOT
id_code: 30001
owner_id: 6
Do i miss something in my code?
Yes, you are missing the fact that you declare and use a pointer to a struct owner, which means that you must initialize it.
So you could do
struct owner *own = calloc(1, sizeof(struct owner));
..
free(own);
but if you don't need to allocate it on heap then you could just allocate it on stack:
struct owner own;
own.tdata.first_name = ...;
Allocating it on the stack wouldn't prevent you from getting the address and pass it to display_my_output function. You just need to call it through display_my_output(&own);.
You need to initialize struct owner *own; using malloc() like this:
own = (struct owner*) malloc(sizeof(struct owner);
and don't forget to free memory at the end:
free(own);
Also, in both your structs, you are making a pointer to an integer rather than integer. I don't think you need an int*.
struct owner *own; declares a pointer to struct owner. Yes, now the compiler knows that the object own points to is a struct owner, but which struct owner is it pointing to? The compiler didn't know, because you didn't tell it.
In fact, an uninitialised pointer may point to an invalid/unavailable memory address, or contain a "trap representation". The result of either of them is undefined behaviour, which causes segfault in your case.
To fix this, write
struct owner *own = malloc(sizeof(struct owner));
The call to malloc() allocates a block of memory to hold a struct owner to own; thus it'll be pointing to valid memory.
Also, don't forget to add free(own) before main() returns, or you will get a memory leak.
Let's say that I was given a struct and I need to assign all of it's attributes to a particular address. The code below is giving me a conditional error, but i'm not trying to evaluate it.
struct header block_o_data;
block_o_data.a = 1;
block_o_data.b = 2;
void* startingAddress = sbrk(0);
&block_o_data = *address;
Please let me know what im doing wrong.
In the assignment to block_o_data, you're taking its address and trying to assign a value to it. The address of a variable is not an lvalue, meaning the expression cannot appear on the left side of an assignment.
You need to declare a pointer to a struct, then assign it the address of where the values actually live:
struct header *block_o_data;
void* startingAddress = sbrk(0);
block_o_data = startingAddress;
Suppose you have a struct like this:
struct mystruct {
int a;
char b;
};
then you probably need something like this:
// A pointer variable supposed to point to an instance of the struct
struct mystruct *pointer;
// This is a general address represented by void*
void *addr = some_function(0);
// Cast that general address to a pointer varibale pointing to
// an instance of the struct
pointer = (struct mystruct *) addr;
// Use it!
printf("%d", pointer->a);
I have declared the structure:
typedef struct keyValuePairs{
char* type;
char* key;
char* valueType;
char* value;
} keyValueType;
keyValueType keyValuePairs[1000];
And in a function declared the local variables as:
char key[500];
char value[500];
to hold the key value pair values as:
key[i]="abc";
value[i]="xyz"
I have assigned these local variables to the global variable as:
keyValuepairs[1].key=key.
Once i come out of the function, the values assigned in the structure is getting lost. Can someone explain where I am going wrong?
Please note I am fairly new to C.
Both key and value variables are pointers to arrays that are allocated in the stack when you are in the function. After keyValuepairs[1].key=key the global variable points to that same place in the stack. After exiting the function, the memory where those arrays were is reused.
I suggest you read up on static vs dynamic allocation in C
If I understand you correctly, you are trying something along the lines of:
typedef struct
{
char* val;
} A;
A alist[10];
void foo()
{
char t[10];
t = "abc";
alist[0].val = t;
}
int main()
{
foo();
}
First of all, the line
t = "abc";
is syntactically incorrect. You have to use something like:
strcpy(t, "abc");
But the most important error is that when you return from foo, alist[0].val points to an address that is not good any more. To make sure alist[0].val points to a valid address, you have to allocate memory from the heap for it and copy the contents of t to it.
void foo()
{
char t[10];
strcpy(t,"abc");
alist[0].val = malloc(strlen(t)+1);
strcpy(alist[0].val, t);
}
To do a thorough job, you'll have to make sure that you call free on that allocated memory at some point before you return from main.
You have not allocated memory for type, key, valueType and value.
Try static memory allocation :
typedef struct keyValuePairs{
char* type[n];
char* key[n];
char* valueType[n];
char* value[n];
}
Where n is a defined constant
Code is as follows:
/* set.h */
struct setElement{
char *element;
setElement *next;
};
typedef struct setElement *Set; //Set is now the equivalent of setElement*
Set a;
setInit(&a);
/* setInit function declaration # setInit.c */
int setInit(Set *a){
(*a)->element = "asdf"; //results in a seg fault
}
Trying to malloc 'a' works, but if I try to access any member within the set 'a' doesn't work. I understand I'm passing a reference of the set from the main() function to setInit, so I believe the pointer contained within setInit is addressing the memory allocated by 'Set a' in the main() function, so a malloc wouldn't be required...
Iunno. Help is appreciated :)
The problem is that you have not allocated the setElement you are trying to assign to. In the main part of the code you are creating a Set, which is just a pointer to a setElement. This pointer is never set to point to anything sensible. I.e. you need something like
Set a = malloc(sizeof(setElement));
Alas, it is unclear where exactly your variables are defined. I assume your main.c is something like
#include "set.h"
Set a;
int main()
{
setInit(&a);
}
If so, your a, which is a pointer by itself, should point to somewhere.
If your framework wants malloc()ed data, you should do
int main()
{
a = malloc(sizeof(*a)); // *a is a struct setElement now, with 2 pointer-sized members.
setInit(&a); // Now seInit should be able to operate on the struct as wanted.
}
As #amaurea has mentioned, you'll need to make use of malloc() for your setElement structure. In addition to this, you need to do the same for the setElement struct's element member. A char* is merely a pointer to a char or char array and will not implicitly allocate anything.
int setInit(Set *a){
(*a)->element = "asdf"; //results in a seg fault
}
Could be re-written
int setInit(Set *a){
(*a)->element = malloc(sizeof("asdf"));
strcpy((*a)->element,"asdf");
}
Which the above could be rewritten to take a second parameter of the actual element contents.