Jack said:
Hello. I have a few questions about allocating memory to a 32k (approx)
character buffer declared as:
This already gives you a 2-dimensional array with 415x78 bytes
of memory assigned to it. So there actually is no need at all
for allcation.
To be more precise, it's a multidimensional array that is my memo
body for a messaging system I am writing. 415 lines by 78 characters,
yields about 31.9k. Therefore, is the following malloc statement correct?
if ((string[215][0] = (char)malloc(32000)) == NULL);
I'm 99% sure its wrong. It compiles OK
This is about as wrong as you can get;-) And it compiles "OK"
only because you silenced the compiler by a cast. I also guess
that the '215' above actually was meant to be '415'. Now if
you do
string[415][0] = (char)malloc(32000)
then several bad things happen. First of all you assign to an
element with indices 415,0 of the 2-dimensional array. That's
an element that is past the end of that array, which already
leads to undefined behaviour. And what you assign to it is
the value that results when you convert an address (that you
received from malloc() to a character value. So, if the address
was e.g. x0x7F265A25 then its conversion to a char value is
probably something like 0x25 (in ASCII the equivalent of the
'%' character) and that's what you're assigning.
None of this obviously is what you planned to do here. First
of all, you already have defined an 2-dimensional array named
'string' with the size you seem to need. And by defining the
array you already made the compiler take care of organizing
the required memory. So there's no point at all in allocating
further memory - you already got all you will ever need with
that array.
And since an array already comes with all the memory needed
you can't assign memory to it. All you can do is assign to
its elements. That's what you did above. And that's also why
you thought you had to add a cast - without it the compiler
would rather likely have grumbled about you trying to assign
a void pointer to something that's a char (assuming that you
have included <stdlib.h> which has the declaration of the
malloc() function, which in turn tells the compler that
malloc returns a void pointer). The cast just kept the com-
piler from telling you about the problem.
I don't know what your intentions actually are and if you
really want to dynamically allocate memory or if having a
finished-for-use array isn't already all you need. If you
want to work with allocated memory for some reasons (e.g.
because you don't know in advance how many lines there will
be needed to be stored or how long the lines will be) then
you will have to work with pointers or arrays of pointers
and assign what malloc() returns to these pointers.
E.g., if the line length is not known in advance but you
know that you'll never need nore than 415 lines you might
do
char *strings[ 415 ];
for ( size_t i = 0; i < 415; ++i )
strings[ i ] = malloc( MAX_STRING_LENGTH );
That would give you an array of 415 char pointers, with
each of them initialized to point to memory for
'MAX_STRING_LENGTH' chars, i.e. each could hold a line
with a length of up to 'MAX_STRING_LENGTH-1' chars (plus
the trailing '\0' character at the end of the string).
Or, if don't know the number of lines nor the lengths
of the lines in advance, one thing you might do is
char ** strings = malloc( NUM_STRINGS * sizeof *strings );
for ( size_t i = 0; i < NUM_STRINGS; ++i )
strings[ i ] = malloc( MAX_STRING_LENGTH );
to get memory for NUM_STRINGS char pointers that in turn
get initilized to point to memory for 'MAX_STRING_LENGTH'
chars.
Of course, there are lots of further variations. If you
tell a bit more about what you want to do it's going to
be easier to come up with a reasonable way to dynamically
allocate the required memory (if that is necessary at all).
Regards, Jens