initialising a structure through pointer - c

Suppose we have
struct me {
int b;
};
void main() {
struct me *m1;
m1->b=3;
}
My quesrion is that , as m1 is a pointer of type me and is currently
not holding any address of variable of type me then how we can access b which is member of me
through a pointer which is not pointing to any variable of type me and if we can then which variable of type me is accesing a?

It's either
struct me m1;
m1.b = 3;
or
struct me *m1 = malloc(sizeof(struct me));
m1->b = 3;
When you deal with pointers in C, you usually need to do 3 things:
create the pointer
make sure the memory is allocated where the pointer should point
make the pointer point to that memory
Your solution only did the first of these.
The reason why your printf works, is that the actual assignment and reading still works. You were overwriting some random memory in your process, this time without any disastrous result. But it's pure "luck". You could have ended up with a segmentation fault as well.

1) You must allocate space for the object you're pointing to first
2) Then - and only then - can you assign the value m1->b = 3

void main()
{
struct me *m1=malloc(sizeof(struct me)); //here allocating the memory first
m1->b=3;
//do what you want to do
free(m1); //once you allocate the memory, you have to free it after your job is done
}
If you do not allocate memory and access (like you have done), you are accessing a part of memory where m1 points to. It will compile fine. But if m1 has a value outside the segment of your code, it will give rise to segmentation fault. Also if it is within your segment, it may overwrite other values. So it is always desirable to allocate the memory before using it.

Related

When writing a function that returns pointer, why should I allocate memory to the pointer I'm going to return?

I'm a bit weak when it comes to memory allocation and pointers.
So, I want to understand why do I have to allocate memory to pointers in functions as follow:
char *cstring(char c, int n)
{
int i = 0;
char * res;
res = malloc ((n+1)*sizeof(char));
while (i<n)
{
res[i]=c;
i++;
}
res[i] ='\0';
return res;
}
and why is the following not valid?
char *cstring(char c, int n)
{
int i = 0;
char * res;
while (i<n)
{
res[i]=c;
i++;
}
res[i] ='\0';
return res;
}
I understand that I should allocate memory (generally) to pointers so that they have defined memory.
However, I want to mainly understand how is it related to the concept of stack and heap memories!
Thanks in advance!
Pointers need to point to a valid memory location before they can be dereferenced.
In your first example, res is made to point at a block of allocated memory which can subsequently be written to and read from.
In your second example, res remains uninitialized when you attempt to dereference it. This causes undefined behavior. The most likely outcome in this case is that whatever garbage value it happens to contain will not be a valid memory address, so when you attempt to dereference that invalid address your program will crash.
If you declare a variable like that,
int A = 5;
then that means the variable will be on the stack. When functions are called, their local variables are pushed to the stack. The main function is also an example of that. So you don't have to allocate memory manually, your compiler will do this for you in the background before it calls your main function. And that also means if you examine the stack during the execution of the function you can see the value 5.
With this,
int A = 5;
int *PtrToA = &A;
The pointer will be on the stack again. But this time, the value on the stack just shows the memory address of the actual integer value we want. It points to the address of the memory block that holds the value 5. Since A is held in the stack here, pointer will show a memory address on the stack.
Like the case in your question you can allocate memory dynamically. But you have to initialize it before you read it. Because when you request to allocate the memory, your operating system searches for a valid memory field in your programs heap and reserves that for you. Than it gives you back its adddress and gives you the read write permissions so you can use it. But the values in it won't contain what you want. When compiler allocates on stack, the initial values will be unset again. If you do this,
char *res;
res[1] = 3;
variable res will be on the stack and it will contain some random value. So accessing it is just like that,
(rand())[1] = 3;
You can get an access violation error because you may not have permission to write to that memory location.
An important note; after your function call returns, values of local variables on the stack are no more valid. So be careful with that. Do not dereference them after the function call ends.
In conclusion; if you want to use a pointer, be sure it points to a valid memory location. You can allocate it yourself or make it point another memory address.
The second version of your code declares a pointer, but does not initialize it to point to a valid memory address.
Then, the code dereferences that pointer -- during the loop. So, your code would access uninitialized memory in this case. Remember, array indexing is just syntactic sugar for dereferencing -- so your code accesses memory its not supposed to.
The first version of your code initializes the pointer to actually point to something, and hence when you dereference it during the loop, it works.
Of course, in either case, you return the pointer from the function -- its just that in the first version it points to something valid, whereas in the second version it points anywhere.
The moral here is to always initialize your variables. Not doing so could result in undefined behavior in your code (even if it appears to work sometimes). The general advice here is to always compile your code using at least some compilation flags. For example in gcc/clang, consider -Wall -Werror -Wextra. Such options often pick up on simple cases of not initializing variables.
Also, valgrind is a brilliant tool for memory profiling. It can easily detect uses of uninitialized memory at runtime, and also memory leaks.
Simple: because you do not have any allocated memory for the data you wite. In your example you define pointer, you do not initialize it so it will reference random (or rather not possible to predict) place in the memory, then you try to write to this random memory location.
You have 2 Undefined Behaviours here in 5 lines example. Your pointer is not initialized, and you did not allocate any valid memory this pointer to reference.
EDIT:
VALID
char *cstring(char c, int n)
{
char * res;
res = malloc ((n+1)*sizeof(char));
char *cstring(char c, int n)
{
char * res;
static char buff[somesize];
res = buff;
char buff[somesize];
char *cstring(char c, int n)
{
char * res;
res = buff;
INVALID
char *cstring(char c, int n)
{
char * res;
char buff[somesize];
res = buff;

Difference in creating a struct using malloc and without malloc

Could someone please explain to me the difference between creating a structure with and without malloc. When should malloc be used and when should the regular initialization be used?
For example:
struct person {
char* name;
};
struct person p = {.name="apple"};
struct person* p_tr = malloc(sizeof(struct person));
p_tr->name = "apple";
What is really the difference between the two? When would one approach be used over others?
Having a data structure like;
struct myStruct {
int a;
char *b;
};
struct myStruct p; // alternative 1
struct myStruct *q = malloc(sizeof(struct myStruct)); // alternative 2
Alternative 1: Allocates a myStruct width of memory space on stack and hands back to you the memory address of the struct (i.e., &p gives you the first byte address of the struct). If it is declared in a function, its life ends when the function exits (i.e. if function gets out of the scope, you can't reach it).
Alternative 2: Allocates a myStruct width of memory space on heap and a pointer width of memory space of type (struct myStruct*) on stack. The pointer value on the stack gets assigned the value of the memory address of the struct (which is on the heap) and this pointer address (not the actual structs address) is handed back to you. It's life time never ends until you use free(q).
In the latter case, say, myStruct sits on memory address 0xabcd0000 and q sits on memory address 0xdddd0000; then, the pointer value on memory address 0xdddd0000 is assigned as 0xabcd0000 and this is returned back to you.
printf("%p\n", &p); // will print "0xabcd0000" (the address of struct)
printf("%p\n", q); // will print "0xabcd0000" (the address of struct)
printf("%p\n", &q); // will print "0xdddd0000" (the address of pointer)
Addressing the second part of your; when to use which:
If this struct is in a function and you need to use it after the function exits, you need to malloc it. You can use the value of the struct by returning the pointer, like: return q;.
If this struct is temporary and you do not need its value after, you do not need to malloc memory.
Usage with an example:
struct myStruct {
int a;
char *b;
};
struct myStruct *foo() {
struct myStruct p;
p.a = 5;
return &p; // after this point, it's out of scope; possible warning
}
struct myStruct *bar() {
struct myStruct *q = malloc(sizeof(struct myStruct));
q->a = 5;
return q;
}
int main() {
struct myStruct *pMain = foo();
// memory is allocated in foo. p.a was assigned as '5'.
// a memory address is returned.
// but be careful!!!
// memory is susceptible to be overwritten.
// it is out of your control.
struct myStruct *qMain = bar();
// memory is allocated in bar. q->a was assigned as '5'.
// a memory address is returned.
// memory is *not* susceptible to be overwritten
// until you use 'free(qMain);'
}
If we assume both examples occur inside a function, then in:
struct person p = {.name="apple"};
the C implementation automatically allocates memory for p and releases it when execution of the function ends (or, if the statement is inside a block nested in the function, when execution of that block ends). This is useful when:
You are working with objects of modest size. (For big objects, using many kibibytes of memory, malloc may be better. The thresholds vary depending on circumstances.)
You are working with a small number of objects at one time.
In:
struct person* p_tr = malloc(sizeof(struct person));
p_tr->name = "apple";
the program explicitly requests memory for an object, and the program generally should release that memory with free when it is done with the object. This is useful when:
The object must be returned to the caller of the function. An automatic object, as used above, will cease to exist (in the C model of computation; the actual memory in your computer does not stop existing—rather it is merely no longer reserved for use for the object) when execution of the function ends, but this allocated object will continue to exist until the program frees it (or ends execution).
The object is very large. (Generally, C implementations provide more memory for allocation by malloc than they do for automatic objects.)
The program will create a variable number of such objects, depending on circumstances, such as creating linked lists, trees, or other structures from input whose size is not known before it is read.
Note that struct person p = {.name="apple"}; initializes the name member with "apple" and initializes all other members to zero. However, the code that uses malloc and assigns to p_tr->name does not initialize the other members.
If struct person p = {.name="apple"}; appears outside of a function, then it creates an object with static storage duration. It will exist for the duration of program execution.
Instead of struct person* p_tr = malloc(sizeof(struct person));, it is preferable to use struct person *p_tr = malloc(sizeof *p_tr);. With the former, a change to the p_tr requires edits in two places, which allows a human opportunity to make mistakes. With the latter, changing the type of p_tr in just one place will still result in the correct size being requested.
struct person p = {.name="apple"};
^This is Automatic allocation for a variable/instance of type person.
struct person* p_tr = malloc(sizeof(person));
^This is dynamic allocation for a variable/instance of type person.
Static memory allocation occurs at Compile Time.
Dynamic memory allocation means it allocates memory at runtime when the program executes that line of instruction
Judging by your comments, you are interested in when to use one or the other. Note that all types of allocation reserve a computer memory sufficient to fit the value of the variable in it. The size depends on the type of the variable. Statically allocated variables are pined to a place in the memory by the compiler. Automatically allocated variables are pinned to a place in stack by the same compiler. Dynamically allocated variables do not exist before the program starts and do not have any place in memory till they are allocated by 'malloc' or other functions.
All named variables are allocated statically or automatically. Dynamic variables are allocated by the program, but in order to be able to access them, one still needs a named variable, which is a pointer. A pointer is a variable which is big enough to keep an address of another variable. The latter could be allocated dynamically or statically or automatically.
The question is, what to do if your program does not know the number of objects it needs to use during the execution time. For example, what if you read some data from a file and create a dynamic struct, like a list or a tree in your program. You do not know exactly how many members of such a struct you would have. This is the main use for the dynamically allocated variables. You can create as many of them as needed and put all on the list. In the simplest case you only need one named variable which points to the beginning of the list to know about all of the objects on the list.
Another interesting use is when you return a complex struct from a function. If allocated automatically on the stack, it will cease to exist after returning from the function. Dynamically allocated data will be persistent till it is explicitly freed. So, using the dynamic allocation would help here.
There are other uses as well.
In your simple example there is no much difference between both cases. The second requires additional computer operations, call to the 'malloc' function to allocate the memory for your struct. Whether in the first case the memory for the struct is allocated in a static program region defined at the program start up time. Note that the pointer in the second case also allocated statically. It just keeps the address of the memory region for the struct.
Also, as a general rule, the dynamically allocated data should be eventually freed by the 'free' function. You cannot free the static data.

Union as a Structure Variable in C

I have the following structures:
complex_attribute
generic_attribute
I defined a union of these two, like so:
union union_attribute{
struct complex_attribute *complex;
struct generic_attribute *generic;
};
And then i defined another structure which keeps track of the union and a code associated with it:
struct tagged_attribute{
int code;
union union_attribute *attribute;
};
Then, i defined another structure called Disk, which contains an array of pointers to tagger_attribute objects:
struct disk {
struct tagged_attribute *attribute_ptr[100];
}
Now I am trying to access the code of the tagged attribute like this:
printf("%i", disk_ptr->attribute_ptr[counter]->code);
But I am getting a segmentation fault. Is my way of accessing the structure variable "code" incorrect?
Here is all of the relevant code from where I am trying to access "code":
struct disk* construct_disk(char* name, char* serial, char* vendor, char* model, int RPM, char *raid_type, int num_args, ...){
struct disk *disk_ptr;
disk_ptr = malloc (sizeof (struct disk));
va_list ap;
va_start(ap, num_args);
int counter;
int incrementer;
//subattributes is a global variable
incrementer = subattributes[counter];
for(counter = 0; counter < num_attributes; counter++, incrementer = subattributes[counter]){
printf("Counter = %i\n", counter);
printf("incrementer = %i\n", incrementer);
if (1){
printf("Populating generic attribute");
printf("%i", disk_ptr->attribute_ptr[counter]->code);
//disk_ptr->attribute_ptr[counter]->code = GENERIC_ATTRIBUTE_TYPE;
//disk_ptr->attribute_ptr[counter]->attribute->generic = construct_generic_attribute(va_arg(ap, int));
}else{
printf("Populating complex attribute");
//struct generic_attribute* input_to_complex_attribute[incrementer];
//int stepper;
//for(stepper = 0; stepper<incrementer; stepper++){
// input_to_complex_attribute[stepper] = construct_generic_attribute(va_arg(ap, int));
//}
//disk_ptr->attribute_ptr[counter]->code = COMPLEX_ATTRIBUTE_TYPE;
//disk_ptr->attribute_ptr[counter]->attribute->complex = construct_complex_attribute(5, incrementer, input_to_complex_attribute);
}
}
va_end(ap);
return disk_ptr;
}
You aren't accessing code at all (which you should be using to check which union member is valid, of course).
You're accessing the counterth element of the attribute_ptr array, which is a pointer to a tagged_attribute and trying to dereference it (with ->). Possibly without allocating that pointer (or any of the others in that array) first, nor initialising the memory after allocation (you haven't shown anything about that... failure to allocate correctly is a likely cause of your segfault.)
Of course, this assumes disk_ptr has been allocated and initialised correctly... which you haven't shown and may not have.
As already mentioned, show all relevant code if you want a more specific answer to your question. Further, compile with warnings enabled and learn to use tools such as gdb (GNU debugger) and valgrind (for memory issues) to debug your code.
EDIT: Now that you've added code, you have allocated disk_ptr but you never allocate anything in attribute_ptr, so it's just 100 pointers pointing to arbitrary places in memory.
You are dereferencing disk_ptr->attribute_ptr[1], but that array of pointers is not initialized (the pointers point nowhere).
You have to malloc the struct tagged_attribute entries for each pointer first.
In C if a pointer is not pointing to valid memory you will have undefined behavior. One of the common things that happens is a segmentation fault as the pointer has random chunk or was initialized to zero and when you try to access the memory it is pointing to the hardware detects that you are accessing an invalid memory page. Every time you use -> you are dereferencing the pointer and run the risk of a seg fault. You should use a debugger to find the incorrect value. An alternative is to print the values before you dereference them:
printf("disk_ptr = %p\n", disk_ptr);
printf("disk_ptr->attribute_ptr[counter] = %p\n", disk_ptr->attribute_ptr[counter]);
You should place this code before the print that you shows. If disk_ptr is an invalid value the second print will fail. The first print will always succeed but you should see if it is NULL or not. If you do not see the second print that means the disk_ptr is an invalid pointer. This because in the second print disk_ptr is dereferenced via the -> operator and if it points to chunk it could (let me emphasize could) cause a seg fault (it could also overwrite some other data which might cause a seg fault later). If the second print works but the print you shows does not then disk_ptr->attribute_ptr[counter] could be the invalid pointer. Let me emphasize again because it is important. If a pointer is not pointing to a correct memory location you have undefined behavior. Dereferencing that pointer could cause a seg fault right there or could modify memory in some way such that a seg fault occurs later.

Variable Declaration in C

I am trying to declare a integer variable m and a pointer to integer data type n.
int m,*n;
*n=2;
printf("%d",*n);
above code works fine.
But
int *n,m;
*n=2;
printf("%d",*n);
gives segmentation fault.
please explain why?
Both versions are wrong—you just got lucky with the one that worked. You've declared a pointer but not allocated any storage for it. Try this:
int *n,m;
n=&m;
*n=2;
printf("%d",*n);
Or using malloc():
int *n;
n=malloc(sizeof(int));
*n=2;
printf("%d",*n);
free(n);
Both code segments invoke undefined behaviour, because you dereference an uninitialized pointer. When there is UB, nasal demons fly out of your nose... or your program orders pizza, or it crashes, or it works... You must alllocate memory first.
int* n = malloc(sizeof(int));
*n = 2;
free(n);
Or set it to an address of another object;;
int *n, m;
n = &m;
*n = 2;
When you declare a pointer variable, it allocates some block of space in memory. This space already contains some data left over from whatever it was used for before this program. It gives a segmentation fault because whatever data is in the pointer refers to a memory location outside of your space on the hard drive. As Armen said, you have to initialize the pointer by telling it where to point. This will replace the data currently in the pointer with the address of your variable m (or wherever you want it to point).
n is uninitialized pointer. Access to it causes error.
You are lucky the first one works at all. Both of them are accessing a non-initialized pointer.
What does "n" point to? Since it is uninitialized, it is pointing to nothing. In each case, you are assigning whatever n is pointing to the value of 2. The first will eventually lead to a nasty bug. You are lucky on the second one because it crashed right away.
Use malloc to create some memory for n to point to, and then assign it.

Memory management in C

Suppose I have a structure, and a pointer to a memory location p, how do I make sure that while creating an instance 'a' of the structure, it is placed into a memory chunk starting at p?
So I am passed a chunk of memory and I want to create a node at the beginning of it, so I need to make sure that the node is created at the beginning of it. (Note: I cannot use malloc, calloc, free, memcpy, or similar functions because I am writing code for a memory management system).
You don't really 'create' instances of structures in C like that. Assuming that p points to a block of usable memory, you can just treat p as a pointer to your structure type:
typedef struct {int x; long y;} a;
a *p2 = (a*)p;
int z = p2->x;
// or, if you don't want p2:
z = ((a*)p)->x;
Once p is cast (implicitly or explicitly as above), you can initialize the contents of your structure however you wish.
As an example, the following code will initialize a structure as you seem to request:
typedef struct {int x; float y;} tA;
void initA (void *p) {
tA *p2 = (tA*)p;
p2->x = 0;
p2->y = 3.14159;
}
int main (void) {
char bigmem[100];
initA (&(bigmem[0]));
return 0;
}
Don't get hung up on the main function above, it's only to illustrate how you can pass an arbitrary memory address to the function. In your real-world case, you will have the memory already allocated somehow.
If creation of the instance 'a' involves allocation of memory, then you can't make that allocation occur at memory pointed to by 'p'.
However, if by creation you mean initialisation of a structure in already allocated memory, then you should be able to pass 'p', typecast to a pointer to the structure, to the initialisation routine. But you will have to be careful that the memory pointed to by 'p' is large enough for the structure, is not being used for something else, and has the right alignment for the structure you are initialising.
If you are actually trying to do something else, you should post some code or go into a bit more detail.
just typecast the pointer to the type of your struct and you are done...
Hope it helps!
Basically, you take the address and cast it to a pointer of the appropriate type. The major problem you can run into is alignment: if the address isn't properly aligned for an object of that type, attempting to dereference the pointer can (and will) cause undefined behavior -- a typical reaction will be your program being aborted. If memory serves, a typical Unix kernel will give you an error message about a "bus error".
You can't control where the allocator will allocate memory from, but you can make a temporary instance (on the stack) and copy it into where p points with memcpy.
(Assuming p points to validly allocated memory, large enough for your structure and aligned appropriately.)
typedef struct {int x; long y;} A;
// Populate the members individually
A *aPtr = malloc(sizeof(A));
aPtr->x = 1;
aPtr->y = 2;
or
A *aPtr = malloc(sizeof(A));
A a;
a.x = 1;
a.y = 2;
// Use C's inherent "assignment == copy by value" capability
*aPtr = a;
or
A *aPtr = malloc(sizeof(A));
A a;
a.x = 1;
a.y = 2;
// Copy the memory yourself
memcpy(aPtr, &a, sizeof(A));
Feel free to replace my malloc with your own malloc.
Sounds like you are trying to do something similar to C++ placement new.
I think you confusing C with higher level languages. You never instantiate structs. You just allocate a bunch of memory and then cast those to a a struct pointer. Alternatively you allocate it on a stack which just means that compiler reserves so many bytes for you to use.
Code example for what Alex says:
struct foo {
int a;
char *b;
float c;
};
struct enough_space_for_a_foo {
char a[sizeof(struct foo))];
};
int main() {
// region of memory, which in the real code someone else is giving us
struct enough_space_for_a_foo memory_region;
// temporary object
struct foo tmp = {10, "ten", 10.0};
// copied to the specified region
memcpy(&memory_region, &tmp, sizeof(struct foo));
}
So, an arbitrary memory region now contains the same values as if it had been initialized as a struct foo, using the initializer expression {10, "ten", 10.0}.
If your struct doesn't need initializing with particular values, then you don't need to do anything. A region of memory in C basically is an instance of a struct if you choose to think of it as one (and it's big enough, and correctly aligned). There are no constructors, so just cast the pointer and get on with filling in the fields.
You asked just the right person. Not specifically, of course.
The answer depends on your OS. If you truly can't use anyone else's memory stuff, then you have your work cut out for you. You will have to make some kind of heap structure(s), perhaps some free list allocators for fixed size, and figure out what the OS has to offer. You have VirtualAlloc in windows and you have brk or similar in unix.
If this is really homework, this is way too much work if this is a single semester assignment.
Of course if all you want to know is how to prepend allocation size to what you return, just do whatever your code normally is, then put your value at the front, then advance the pointer by one and return that.

Resources