Hello, and welcome back. In this lecture, I want to provide a demonstration for our previous
challenge,
which was getting you to understand how to
allocate memory dynamically using malloc.
We're just going to do some simple reading from the keyboard and then
displaying a string, but we're going to use it
with dynamically allocated pointers,
character pointers.
So let's bring up code blocks create a new project.
And we're just going to name this one dynamic memory allocation example.
And the first thing you need to do when you're
going to utilize dynamic memory allocation is you have to make sure you're including standard lib.
Luckily when you create a project in code blocks,
it'll automatically include it for you.
But the reason we need to include standard lib is because malloc,
the malloc function is in there. And malloc, remember, is the main function
to allocate memory. You also have calloc.
Calloc is really important because calloc will
do some of the nice calculating of how many
bytes you need because that's two parameters.
But the real good thing about calloc is it initializes all the data
to zeros if they're ints and so forth, really nice function.
You have realloc. Realloc will extend memory that's
already been allocated.So you pass it in a pointer.
From that pointer, it determines how much memory is allocated for it
and it copies everything that was in there to a new memory location,
and then you also specify how many more bytes you want to allocate
just adds it to the new memory location, really nice feature.
But remember that when you're allocating memory for integers using malloc,
you have to determine how much memory you want to allocate bytes,
but you usually want to use the sizeof operator.
So here let's get to that.
In my main method, I'm going to create a integer,
and I'm just going to say that's just going to be size. is going to enter the size of how many bytes
they want to allocate at runtime, so that's going to store the size.
The other thing I want to create is I want to create a char pointer,
and this is just going to be text. And I'm going to initialize this to null
because it's not pointing to anything right off the bat.
Now first thing I want to do is I want to ask the user to enter the size.
So I'm going to say printf,
I'm going to say enter limit of the text.
And they're going to enter a number for how many bytes want to be allocated really
be the number of characters.
And then I'm going to read that in by using scanf.
Scanf, the first parameter is the type of the format specifier for the type of the data.
This is going to be percent d because I'm reading an integer.
And then remember, scanf takes a pointer.
We now know that functions that take pointers,
you need an address to pass in.
So if I'm going to pass in size, size is not an address unless I use the address of operator.
So I'm going to ampersand and I'm going to say size,
that's going to read in the number of bytes.
Once I have the number of bytes,I can now allocate memory for it using the malloc function.
And malloc is going to return a void pointer.
And the pointer is going to be the first address
for that newly allocated memory. So you can assign it right to text.
Because remember, text is a pointer.
We want to point text to this new address that's being returned.
Because malloc returns a void pointer, we have to cast it.
The type of data that we're pointing to is a character so we want to say char star,
and then we can call the malloc function.
The malloc function takes the number of bytes.
And so the number of bytes, if you just passed in the number of bytes,
it's only going to allocate that many bytes. But depending on the type of the data,
the type of the data may be two or four bytes.
So if you wanted to allocate 10 characters,
you want to make sure that you multiply
10 characters times the size of char.
So now we're going to say n
times sizeof. The sizeof operator is often used in the malloc function
because it's machine independent,
and it will tell you how much you actually need to allocate.
Now this is more relevant when you have integers. Remember, integers,
depending on the system that you're on, the architecture that you're running,
integers can be represented by four bytes, two bytes,
usually two or four bytes.
If you were to say I want to store one integer,
so I'm just going to create four bytes of memory, well,
that might not be correct because what if it's two bytes.
So you always want to do
how many integers or how many characters you want to create and then multiply that by
the size of the character on your system. Sizeof operator will give you the number of bytes a char
occupies. So if you want to create 10 chars,
you say 10 times size of char. If you want to create 10 integers
to store 10 integers,
you say 10 times size of int, that's really important.
Now with the calloc function, you don't have to do that. Calloc
actually takes two parameters. And the first parameter
is the
pointer I think and then the second parameter is the size of bytes.
So if you say 24 int, then all you do is you have to pass in
just 24 and automatically allocate for you.
So calloc is a really nice tool to use because you don't have to do this multiplication.
So for calloc, the first parameter is the size.
So if you wanted to create 10 int, you would just pass in 10.
And then the second parameter
is the size of the byte. So you don't have to do the multiplication. It saves you a little bit of the step.
Now that we allocated memory,
you want to make sure that text isn't null before you try to de-reference text.
So you always want to wrap this around a not text,
and that will say it's not null or you can just do explicitly and say
if text is not equal to null.
I always want to do that because it's very, very dangerous
to try to de-reference a pointer.
Anything could happen. You might be able to write data into it.
into it. It would just write it somewhere else in memory. So
it would screw up your program or you may have a segmentation fault and the program may crash.
But as long as you really allocate that memory,
you can now actually read in some data.
You can use git s or you can use scanf here.
But what you want to do is you want to print out,
enter some text
and we also want to add line feeds here so they're easy to read.
And we'll use scanf since that's what we're familiar with.
And scanf is just going to read in
percent.
Actually, I'm going to show you a trick.
I'm going to use scanf to read in the next character so it pauses
and then I'm going to use get s to read in the text.
And gets is just another function usually you can use the f gets. You just have to set it to the
set it to the input stream.
But gets is going to read from the standard input stream, which by default is the keyboard.
And gets is going to takes a pointer. So all we have to do is pass in text
because it's already a pointer, we don't have to put in the address of operator.
And the nice thing with get asks is that you can read in multiple strings separated by spaces.
Once we actually read in gets,
we can just print it out. So we can say inputted text if inputted is a word
percent s backslash n
and then comma text. Text is a pointer.
Printf takes a pointer. We don't have to de-reference it.
Because if you just display text,
text is going to display the value of the pointer which is going to be an address.
We actually want to display the value of what text is pointing to.
And then we're done. Oh nope, we definitely are not done. We want to call our free.
We want to free our pointer.
Even though when we exit, the memory is going to be free. We still want to make sure that we free it,
and then we also probably want to just for safekeeping, we want to set text equal to null.
So let's go ahead and build this and see what happens.
And I do have a problem because I'm not reading
in the right variable.
so here I'm not using the right variable. I want to use size,
and
it looks like we're good.
So here we go the one difference here is you don't have to de-reference the text
because text is a character pointer.
You only have to de-reference if in pointer and so forth. So you just
when you use the percent s, it automatically knows to de-reference the
character pointer.
That's one difference when you're using character pointers versus
other pointers.The other pointers you have to de-reference to get the value
because you can't actually copy
strings to string arrays and so forth.
You would never be able to do star text equals,
you'd have to always use the str copy if you want to copy text.
Because remember from the lectures, you can't actually assign
data to an array, and a character pointer is an array.
So here this looks correct. No reason to de-reference it.
We want to build this, and then we want to run it.
And you'll notice we put the limit of the text.
So say we put in 5, 6 for jason
and it prints out input is jason.
And you can play around with this program. But again, the takeaways from this
include standard lib when you're doing malloc.
Initialize your character pointers to null. Do a scanf,
use the ampersand because size is not a pointer.
When you're mallocing, malloc returns a void pointer, so you have to cast.
You always want to inside your malloc. Do the sizeof operator
for what you want to allocate for. Times, how many actual characters
are or integers. This is more applicable to integers and primitive data types
technically for characters. You can just do size, that should work fine.
You always want to check for null, make sure it's not null.
When you go to use character string.
And then we just enter some text, stored in our gets and print it out.
And then last but not least, we always want to free our pointers
so that we can give that back to the heap. Hope this helps. Thank you.