Do every variable declared as pointer have to allocate memory? - c

Well, I am new to C. I would like to know as my title says.
Suppose I declare pointers as following,
char *chptr1;
char **chptr2;
int *i;
int **ii;
struct somestruct *structvar1;
struct somestruct **structvar2;
Then,
Do I need to allocate memory for every variable, before storing data into them?
Is there any special case when I do not need to allocate memory for them? for this I know one for char pointer,
strdup() which allocate memory itself, we have not to care much about it.
Any further suggestions are welcome.

Pointers point at things. It's up to you what you make them point at.
You can leave them uninitialized and don't use them: int * q; That's a little silly.
You can make them point to something that exists: int x; int * q = &x;
You can store the address of dynamically allocated memory in them: int * q = malloc(29);

First thing you need to understand is, pointers are variables which are used to store addresses of memory or addresses of other variables. When you declare a pointer, you are allocating memory for that pointer and not to data pointing by that pointer.
For example,
char *ptr; //Here you allocated memory for pointer variable.
ptr = malloc(sizeof(char)); // allocated memory for the data pointed by ptr
Then call free() after using memory
free(ptr); // DE-allocates memory pointed by ptr and not variable ptr.

Do I need to allocate memory for every variable, before storing data into them?
It depends on the use case.
Let's assume you have aprogram where you can enter a user name, but if no user name is entered, a hardcoded value "Default User" is shown. Now you want to pass arround that name. If the user entered a name you might have allocted some space for it, and pass aorund that pointer. If no user name is given you are pointing to that hard coded value, which you already predefined, and you don't need to allocate memory for it.
char const *Default = "Default User"
char *username = NULL;
username = getUser(); // here the name is allocated dynamically if it is present.
if(username == NULL)
username = Default;
In the above case, the sapce for the "Default User" String is already reserved in the executable by the compiler, so you need not to allocate additional memory for it, unless you want to manipulate it.
Another case could be when you program a low level device, and you have a pointer to a hardware buffer provided by the device. In such a case you also wouldn't allocate memory, but you would still use the pointer for that buffer which may be on a fixed address. So you would use the pointer like this (Example which would change the screen border color on a C64):
char *BorderColor = 0xd020;
*BorderColor = 0;

I think that in C, a variable is a pointer added * with a memory. And a pure pointer has no memory. So if we want to store a data, we need to give the pointer a memory.
Sure, there are many ways to assign the memory.
First:
uint32_t x;
uint32_t *p = &x;
uint32_t array[10];
uint32_t *q = array;// equals to int *q = &array[0];
Second:
#define NUM_MACRO ((uint32_t) 10)
//we must free after we using. Or, perhaps we we will get a segment fault.
uint32_t *p = malloc(size(uint32_t) * NUM_MACRO);

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;

Struct pointer syntax confusion

Hi i'm relatively new to c and was wondering if anyone could explain what exactly i'm doing with the following code.
I have a struct:
typedef struct free_list_header {
u_int32_t magic; // ought to contain MAGIC_FREE
vsize_t size; // # bytes in this block (including header)
vlink_t next; // memory[] index of next free block
vlink_t prev; // memory[] index of previous free block
} free_header_t;
and I'm initialising it within a function using the following...
void vlad_init(u_int32_t size)
{
int sizePow2 = pow(2, ceil(log(size)/log(2)));
memory = malloc(sizePow2*sizeof(char));
memory_size = sizePow2;
strategy = BEST_FIT;
free_header_t *freeHeader = (free_header_t*)memory;
freeHeader->magic = MAGIC_FREE; // the unique value
freeHeader->size = memory_size; // amount we malloc'd
freeHeader->next = 0; // position of next free block
freeHeader->prev = 0; // position of prev free block
free_list_ptr = 0;
}
my question is what exactly am i doing here and why is it necessary?
free_header_t *freeHeader = (free_header_t*)memory;
So... i'm declaring a new struct by pointing to it named "freeHeader"? and that is a pointer to it in the memory i have allocated? So this is a way of putting the struct into the malloc'd area to access it out of the function in which im initializing it?
Malloc returns a void pointer (type void*). This means it returns a pointer to a memory address and that pointer is not pointing to any specific type. So after the line:
memory = malloc(sizePow2*sizeof(char)); //sizePow2 is n bytes to allocate
memory is a pointer of type (void *).
free_header_t *freeHeader = (free_header_t*)memory;
On the left hand side here you are creating a pointer named freeHeader that points to a memory address containing something of type free_header_t
Since you explicitly said this pointer is pointing to an address of type free_header_t to you are casting the other side (currently of type void *) to match it as free_header_t *.
NOTE in C, this works but is not necessary. The compiler will automatically cast a void * to whatever type you need. However writing code like this is good practice, in C++ you need to explicitly do this.
free_header_t * freeHeader = (free_header_t*)memory;
you declared a pointer (not an actual struct) to free_header_t struct named freeHeader and you assigned it the value of the pointer named memory. since memory is a pointer to char and yours is a pointer to something else, you used casting.
You currently have only a pointer to an allocated area (of size sizePow2*sizeof(char) - note that the size of the struct should be less or equal to the size of the allocated memory).
Your code is essentially equivalent to:
free_header_t *freeHeader = malloc(sizePow2 * sizeof(char));
It's allocating a block of memory that contains sizePow2 bytes, and then using that as the address of a free_list_header structure.
The reason it uses the memory variable is because some other code is going to use the next and prev members as indexes into that block of memory. As the name implies, this structure just contains the data at the beginning of the memory block, the rest of the memory is managed with other structures.
memory = malloc(sizePow2*sizeof(char));
You are allocating some memory here. It would be good to just use
memory = malloc(sizeof(struct free_list_header));
to store an object of the structure.
free_header_t *freeHeader = (free_header_t*)memory;
Here you are declaring a pointer which would point to memory allocated earlier. You did not technically declare an object of the structure. And you are not putting the structure in to malloc-ed area, you are instead treating the malloc-ed area as an object of the structure.
free_header_t freeHeader = {0}; would be declaring an object of the structure.
Every time you call malloc() function, the operating system returns you a single memory address. When you cast this pointer to a specific type you tell to compiler that every element stored in the memory allocated will consume the size of the specified type and this get the things easier.
Let suppose that you declare a uint64_t* and the size of allocation it's 100 times the size of uint64_t, so you're asking for 800 bytes for the operating system, once the uint64_t takes 8 bytes. If you do not cast this pointer, every time you increase the address with your_variable++ your program will skip only one byte and you will get in the "middle of the number and will get a weird value", but if you cast your pointer to a uint64_t and increase the address with your_variable++ your program will skip 8 bytes, going directly to the next number.
In your example, you're telling to the operating system that your pointer will store types of free_header_t. You're not obligated to do it, but it is a very good practice.
And yes, if you return this address to another function, the other function can change the value stored in this memory area easily.
Hope it helps!

Not sure whether or not to malloc memory for a struct

Suppose I have the following C code:
#include <stdio.h>
#include <stdlib.h>
#define NUM_PEOPLE 24
typedef struct {
char **name;
int age;
} person_t;
void get_person_info(person_t *person);
int main(int argc, char **argv) {
for (int i = 0; i < NUM_PEOPLE; i++) {
person_t new_person;
get_person_info(&new_person);
}
return 0;
}
where get_person_info() just fills out the person_t struct to which a pointer is passed in. Is it necessary to malloc() memory for new_person within main()? That is, should the line
person_t new_person;
instead be
person_t *new_person = (person_t *) malloc(sizeof(person_t));
and then change get_person_info() to accept a person_t ** instead of a person_t *?
Sorry if this question is confusing -- I'm not sure whether or not this is a case where it is necessary to reserve memory, given that a pointer to that memory is passed into get_person_info() to avoid causing a segmentation fault.
Both are correct, it depends on where you want to use the person_info.
Allocating on the stack :
for (int i = 0; i < NUM_PEOPLE; i++) {
person_t new_person;
get_person_info(&new_person);
}
Creates a person_t object on the stack and fills the new_person object with data, because the loop only does that, the object goes out of scope on the next loop iteration and the data is lost.
Using malloc :
for (int i = 0; i < NUM_PEOPLE; i++) {
person_t *new_person = malloc(sizeof(person_t));
get_person_info(new_person);
}
Creates a person_t object on the heap and fills it with data, because its allocated on the heap the new_person object will outlive the loop scope which currently means that you're leaking memory because you have no pointer pointing at the data of the person_t object of the previous loop cycle.
Both ways are correct !!
person_t *new_person = (person_t *) malloc(sizeof(person_t));
and then change get_person_info() to accept a person_t ** instead of a person_t *?
you don't need to change parameter of function -void get_person_infperson_t *person);.Just pass pointer to it in main like this -
get_person_info(new_person);
But in previous way without allocating memory , you won't be able to use it outside the block it is defined in whereas if your program depend on its life you can allocate memory to it on heap.
In your code you posted new_person is used inside loop only so if you don't intend to use to outside loop you probably won't need dynamic allocation .
But if you want to use it outside loop also you should use dynamic allocation. But don't forget to free it.
Not sure whether or not to malloc memory for a struct?
The short answer is: no need to do it in your case. If you want to use your object outside the forloop you could do it by dynamically allocated memory, namely:
person_t *new_person = malloc(sizeof(person_t));
and then call it with:
get_person_info(new_person);
In you example, the object is used within the loop, thus there is no need to do it.
Note:
when you use dynamically allocated memory you should always free it, at the end to avoid memory leaks.
Edit:
As pointed out by #Johann Gerell, after removing the redundancy of the casting of the return type of malloc, in C, the allocation would look like:
person_t *new_person = malloc(sizeof(person_t));
malloc returns a void pointer (void *), which indicates that it is a pointer to a region of unknown data type. The use of casting is required in C++ due to the strong type system, whereas this is not the case in C.
Your confusion stems from not understanding object storage duration and pointers well. Let's see each one separately to get some clarity.
Storage Duration
An object can have automatic or dynamic storage duration.
Automatic
Automatic, as the name says, would be managed by the compiler for you. You just define a variable, use it and when it goes out of scope the object is destroyed automatically for you. A simple example:
if (flag) {
int i = 0;
/* some calc. involving i */
}
// i is dead here; it cannot be accessed and its storage is reclaimed
When the control enters the if's scope, memory large enough to hold an int will be allocated automatically and assigned the value 0. Once your use of i is over, when the control exits the scope, the name i goes out of scope and thus will no longer be accessible by the program and also its storage area allocated automatically for you would be reclaimed.
Dynamic
Lets say you want to have objects dynamically allocated i.e. you want to manage the storage and thereby the lifetime of the object without the scope or the compiler coming in your way, then you'd go on by requesting storage space from the platform using malloc
malloc(sizeof(int));
Notice that we're not assigning the return value of malloc to any pointer as you're used to seeing. We'll get to pointers in a bit, lets finish dynamic objects now. Here, space large enough to hold an int is handed over to you by malloc. It's up to you to free it when you're done with it. Thus the lifetime of this unnamed int object is in your hands and would live beyond the scope of the code that created it. It would end only when you explicitly call free. Without a matching free call getting called, you'd have the infamous memory leak.
Pointers
A pointer is just what its name says - an object that can refer to another object. A pointer is never what it is pointing at (pointee). A pointer is an object and its pointee is another separate, independent object. You may make a pointer point to another named object, unnamed object, or nothing (NULL).
int i = 0;
int *ptr1 = &i; // ptr1 points to the automatic int object i
int *ptr2 = malloc(sizeof(int)); // ptr2 points to some unnamed int object
int *ptr3 = NULL; // ptr3 points to nothing
Thus the reason most people confuse pointers for dynamically allocated pointees comes from this: the pointee, here, doesn't have a name and hence they're referred to always via their pointers; some people mistake one for the other.
Function Interface
The function taking a pointer is appropriate here, since from the caller's viewpoint it's a flexible function: it can take both automatic and dynamic objects. I can create an automatic variable and pass it in, or I can pass a dynamic variable too:
void get_person_info(person_t *person);
person_t o { };
get_person_info(&a);
person_t *p = malloc(sizeof(person_t));
get_person_info(p);
free(p);
Is it necessary to malloc() memory for new_person within main()?
No. You can define an automatic variable and pass it to the function. In fact it's recommended that you try to minimize your usage of dynamic objects and prefer automatic objects since
It minimizes the chances of memory leaks in your code. Even seasoned programmers miss calling the matching free to a malloc thereby introducing a memory leak.
Dynamic object allocation/deallocation is far slower than automatic variable allocation/deallocation.
A lot of dynamic allocation deallocation causes memory fragmentation.
However, automatic variables are generally allocated in the stack and thus the upper limit on the number and size on how much you can create on the stack is relatively lower than what you can allocate dynamically (generally from the heap).
change get_person_info() to accept a person_t ** instead of a person_t *?
No, if you did so, the option of passing automatic variables would still be possible but cumbersome:
void foo(int **o);
int i = 0;
int *p = &i; // p is redundant
foo(&p);
int *p = malloc(sizeof(int));
foo(&p);
As opposed the simpler
void bar(int *o);
int i = 0;
bar(&i);
int *p = malloc(sizeof(int));
bar(p);

how to calculate size of pointer pointed memory?

In one function I have written:
char *ab;
ab=malloc(10);
Then in another function I want to know the size of memory pointed by the ab pointer.
Is there any way that I can know that ab is pointing to 10 chars of memory?
No, you don't have a standard way to do this. You have to pass the size of the pointed-to memory along with the pointer, it's a common solution.
I.e. instead of
void f(char* x)
{
//...
}
use
void f(char *x, size_t length)
{
//....
}
and in your code
char *ab = malloc( 10 );
f( ab, 10 );
It's a deep secret that only free() knows for sure. It's likely in your system, but in a totally implementation dependent manner.
A bit awkward, but if you want to keep everything together:
typedef struct
{ // size of data followed by data (C only trick! NOT for C++)
int dimension; // number of data elements
int data[1]; // variable number of data elements
} malloc_int_t;
malloc_int_t *ab;
int dimension = 10;
ab = malloc( sizeof(*ab) + (dimension-1)*sizeof(int) );
ab->dimension = dimension;
ab->data[n] // data access
I've changed the data type to int to make the code a more generic template.
You can't (portably anyway). You have to keep track of the size yourself.
Some implementations of malloc could give you an API to access that information, but there is no provisions in the standard for this.
The size is what you passed into malloc, you can use a global variable or macro to remember it.
There is no way, you have to store the size of the allocated memory in another variable.
No, unfortunately.
You need to pass the size of the block along with the pointer.
No.
Now, that being said, there are non-portable hacks to do this, but it is not safe to rely upon them.
If you know with 100% certainty that the memory was allocated via malloc(), you may be able to rewind the pointer a few bytes and inspect the 'malloc node' that is used to track which parts of memory have been allocated and which have not. However, I can not stress this enough--do not ever depend upon this.
There is no way to deduce the size of allocated memory from the pointer itself. Since ab is a char *, sizeof(ab) is the same as sizeof(char *), which obviously is not the same as the size of the allocated chunk of memory.
Since you called malloc with the required size, you know what the size is. Pass this number along with the pointer to the function that needs to know the size.
I had a structure and a char pointer pointing to its memory address. So relating it to your question, I wanted to find the size of the memory location it was pointing to i.e. the size of the structure. So logically what you do is, find the size of the object the pointer creates to. This worked for me:
unsigned char * buffer= Library1Structure;
int x=sizeof(Library1Structure);
So the value of x tells me the size of the memory location the pointer buffer points to.

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