How can I declare an array of pointers to arrays of characters in C?

In summary: ArrayTwo=(char*)malloc(strlen(ArrayOne)); This will result in "char *ArrayTwo=(char*)malloc(strlen(ArrayOne));" when executed. The asterisk (*) signifies that this function will allocates memory for an array of characters that is the same length as the string that is passed as its argument.
  • #1
Math Is Hard
Staff Emeritus
Science Advisor
Gold Member
4,652
38
I am not sure I wrote this correctly, but I am trying to declare an array of 12 pointers to arrays of 50 characters:

char *names[12] [50]

Does this look OK? Thanks.
 
Physics news on Phys.org
  • #2
arrays and sizes

I am also not sure why this won't work when I am declaring two arrays.

char ArrayOne[] = "Run, Spot, Run!";
int length =strlen(ArrayOne);
char ArrayTwo[length];

I thought this would declare an array of characters (ArrayTwo)and make it the same length as ArrayOne?
I errors like: "expected constant expression" and "cannot allocate an array of constant size 0"

Why wouldn't this work? Thanks.
 
  • #3
For your first query,
if you want just 12 pointers then char *names[12] would suffice.
However it seems you want to 12 names with 50 characters at max in which case
char names[12][50] would suffice.
why? because the identifier "names" itself is a pointer.
you can access any name just by,
printf("%s",names). (for i betn 1 and 12).

For your second query,
you are not properly instantiating the character array,it should be ...

char ArrayOne[] = "Run, Spot, Run!";
int length =strlen(ArrayOne);
char *ArrayTwo;
ArrayTwo = new char[length];

(i have assumed u are working with cpp)
if u are working with C then use malloc instead of the new operator.

-- AI
 
  • #4
You can not make an array of n dimentions where n is not constant e.g.

int n=10; // not a constant
char mychars[n]; // array of characters
// Wrong

This will result in "expected constant expression"

However if it were

const int n=10; // a constant (hence the "const" type)
char mychars[n]; // array of characters
// Correct

You want to declare an array of n dimentions where n is the length of a string, right?

Do this:

#include <stdlib.h>
char *mystring="Run, Spot, Run!";
char *ArrayTwo=new char[strlen(mystring)];

If you're using an old C/C++ compilier use this to be on the safe side:

#include <stdlib.h>
char *mystring="Run, Spot, Run!";
char *ArrayTwo=(char*)malloc(strlen(mystring));

Hope this helps.

Mike
 
  • #5
Thanks, AI. I am working with C. What does malloc do? I assume it allocates memory?

-Jessica
 
  • #6
And thank you, Mike. I will give that a try.

p.s. I have found that I had to use the include
#include <string.h>
or I got warning messages from Visual C++ compiler. You don't have to use that include with your compiler?

(This is when I am trying to use strlen() I mean. Sorry - I am not being very clear today! :redface: )
 
Last edited:
  • #7
Yes malloc allocates memory.

Also yes u need #include<string.h> for using strlen().
all the string related functions are defined in string.h
these string functions include strlen,strcmp,strcmpi,strtok,strstr and so on...

-- AI
 
  • #8
I had pretty good luck with your suggestions, but I did get a warning that "'malloc' is undefined; assuming extern returning int" so perhaps there is some library that I need to include in the header. I was getting the same warning with strlen() until I put #include <string.h> in the header.
Here's what I have now.

PHP:
#include <stdio.h> 
#include <string.h> 
int main (void) 
{ 
char ArrayOne[] = "Run, Spot, Run!";
char *ArrayTwo=(char*)malloc(strlen(ArrayOne));
return 0;
}
 
  • #9
ooh - found it!

# include<malloc.h>

thank you, Google! :biggrin:
 
  • #10
TenaliRaman said:
Yes malloc allocates memory.

Also yes u need #include<string.h> for using strlen().
all the string related functions are defined in string.h
these string functions include strlen,strcmp,strcmpi,strtok,strstr and so on...

-- AI

Thank you, dear faraway friend! I appreciate your help.
 
  • #11
Don't know about us compiliers but for "string.h" + "alloc.h" all i include is "stdlib.h". It include the other two headers within it.
 
  • #12
What are you trying to do anyway?
 
  • #13
Hi Mike, as far as the "arrays and sizes" question, I am playing around with copying a string from one array to another - without using strcopy() . I was trying to figure out how I could make the second array the same size as my first one, then copy that characters over. I am not quite sure if that's the best way to go about it so I was just experimenting a little bit.
 
  • #14
Keep in mind that the size of an array and the length of a string in that array are not necessarily the same. In fact, they're rarely the same.

If you want to create an array of a size determined only at runtime, you'll need to use the malloc() function (the old C way) or the new operator (the C++ way).

- Warren
 
  • #15
Thanks, Warren. I just started looking at the malloc() function. I am little bit baffled by the RHS of this still

char *ArrayTwo=(char*)malloc(strlen(ArrayOne));

I can see that the string length is returned inside the malloc() function, so is malloc() now setting aside bytes of space to hold the number of characters found by strlen()?
Does malloc() then use the (char*) just before it to know what kind of objects it needs to make room for?

p.s. I don't think I understand what the * after char means in (char*)
 
  • #16
If I remember correctly, malloc() returns void* which you must then cast to whatever pointer type you are using, in your case char*. You may be asking yourself: What is the purpose of casting pointers if they are all basically the same thing (i.e. memory addresses)? Think of it as some rudimentary C type-checking.
 
  • #17
If my strlen() function counts the characters in the string and returns an integer value of 15, then malloc() has the integer value of 15 as an argument.. I think? Does malloc(15) then look at (char*) and interpret the whole thing as "OK I need to make space for 15 chars" ?

what is void*? Is that a null pointer?

Thanks!

(sorry for such basic questions - I am having trouble reading further on in my book until I get a better understanding of this stuff)
 
Last edited:
  • #18
Yes, strlen will return 15. However, to create a proper string with 15 text characters, you need to add one to that in order to have room for the terminating null character.

A void* is a generic pointer. It is the built-in C mechanism for passing around an arbitrary memory address.

malloc does not know what you want memory for -- it just knows that you want a certain amount. So it allocates the memory and gives you the pointer to the memory without according a specific type to the pointer. That is why it is proper to cast the return value to the appropriate pointer type.

char* s2 = (char*)malloc(strlen(s1)+1);

The cast (i.e. the "(char*)" in front of malloc) tells the compiler that while you know that the return value of malloc is not a char*, that you are sure that you want to treat it like one and thus that it is ok to assign the result to a variable of type char*.
 
Last edited:
  • #19
Ahhhh... Slowly the light-bulb is coming on!

So malloc() is returning a pointer, then char* s2 is holding the address that was returned?

Thanks, plover! You're a peach! :smile:
 
  • #20
Code:
char ArrayOne[] = "Run, Spot, Run!";
int length =strlen(ArrayOne);
char ArrayTwo[length];
This listing that you included above is correct C code -- but only if the compiler supports the most recent version of the C standard (known as C99). In VC++ version 6, I'm fairly sure that C99 is not supported. I don't know what support there is in the .NET version.

The deal here is that earlier C standards required arrays to have a size that could be determined at compile time rather than run time. Thus, for older compilers
char a[5];
#define SIZE 12
char b[SIZE];​
are both ok, but
int n = 5;
char a[n];​
is not.

I think that also the C++ standard does yet not allow for these variable length arrays.

As for include files: some compilers (such as GNU's gcc) have a few common C library functions (e.g. printf) built into the compiler, and thus no include directive is strictly necessary when using these functions. However, recognizing these functions without the include directive is non-standard behavior, so depending on this functionality for anything other than informal coding is generally a bad idea. I don't know if strlen is ever one of the built-in functions.

It is also good coding practice not to rely on standard library headers to include other library headers for you.

C pointer declaration syntax - the reason you are confused by this is that, well, it's confusing. :wink: This is not one of C's strong points...

Traditionally C programmers have written pointer declarations like this:
char *s;​
That's because in multiple declarations each pointer requires its own '*':
char *s, *t, *u, v;​
(Note that v is just a regular char not a pointer.)

I personally prefer this equally valid syntax:
char* s;​
which
  • emphasizes that 'pointer-to-char' is the type of s,
  • doesn't have the ambiguity of having *s meaning one thing in the declaration and another when used in later expressions, and
  • makes cast notation like (char*) make more sense.
BUT, using this style means you have to take care never to write:
char* s, t; /* Probably not what was intended */​
and think you have two pointers.

The ambiguity of the *s notation that I mentioned works like this:
char t[] = "Go! See Spot debug!";
char *s = t;
*s = 'L';
Warning: I'm not necessarily recommending that you adopt this style of notation. Notational issues like this are often the cause of religious wars among programmers. It is nearly always best to follow the conventions of whatever group of programmers you happen to be working with.

On the other hand, it is also important to have your style of coding be clear to you. Also, it's good to be familiar with the variants as you may encounter them in other people's code.

I better stop now... :redface:

(How did I end up in this long and ridiculously didactic digression? :eek: I hope at least something in here is helpful...)
 
  • #21
Plover, thanks so much. This is not only so helpful for me, but for the others who come across this thread.

re: It is also good coding practice not to rely on standard library headers to include other library headers for you.

I had better do some more reading about headers.

re: C pointer declaration syntax - the reason you are confused by this is that, well, it's confusing. This is not one of C's strong points...

Gosh, I am so glad you said that - I feel much better! :biggrin:

-Jessica
 
  • #22
If you're new to C/C++, Screw MSVC. The libraries that it has are not very user friendly and it compiles slowly (not really a big deal on new computers though...)

Take a look at http://www.cs.virginia.edu/~lcc-win32/. It has a very nice environment for a newbie programmer, compiles fast, and comes with a very nice Garbage Collector interface.
 
  • #23
Thanks. I'll take a look at that - even though I am really apprehensive about giving up the environment I am used to. What's a "Garbage Collector" interface?
 
  • #24
"Garbage Collection" in a computer program is an automatic system for detecting when pieces of allocated memory are no longer being used and automatically releasing them to the pool of unused memory.

When a C program starts the run-time environment establishes a section of memory called "the heap"; routines that allocate memory dynamically (such as malloc) find an unused chunk of the heap, mark it as "in-use", and return its address to the user. This chunk of memory is now unavailable for any other use until it is released.

Non-dynamic uses of memory (such as variables declared within functions) are not a problem. Memory for these is allocated in a different fashion that ensures that the memory is released at the end of the function. But one common reason for allocating memory dynamically is that
it may be unknown how long the program will require a particular piece of data.

A chunk of memory from the heap becomes completely inaccessible, and thus unrecoverable, when there are no more pointers to the chunk. (Either because the last pointer was assigned to point somewhere else, or simply vanished at the end of a function.) At this point, if a system has garbage collection, it will notice that the chunk of memory has been orphaned and make sure it is marked as available again. In a non-garbage collecting environment, like most C and C++ environments, allowing this to happen is what programmers call a "memory leak", i.e. usable memory is "leaking" out of your heap. The mechanism to deal with this in standard C is a function called "free" (which should be detailed alongside malloc in your documentation). When finished with a dynamically allocated chunk of memory, you pass a pointer to the chunk as an argument to "free" and the chunk is returned to the heap.

While the C standard does not specify any facilities for garbage collection, there is no reason why a given compiler/development environment can't include one. It will, however, most likely be specific to that environment, so if it is important that your code be portable, it is a bad idea to rely on such a facility.
 
Last edited:
  • #25
plover said:
"Garbage Collection" in a computer program is an automatic system for detecting when pieces of allocated memory are no longer being used and automatically releasing them to the pool of unused memory.

When a C program starts the run-time environment establishes a section of memory called "the heap"; routines that allocate memory dynamically (such as malloc) find an unused chunk of the heap, mark it as "in-use", and return its address to the user. This chunk of memory is now unavailable for any other use until it is released.

That's very interesting. How big is a heap?
Non-dynamic uses of memory (such as variables declared within functions) are not a problem. Memory for these is allocated in a different fashion that ensures that the memory is released at the end of the function. But one common reason for allocating memory dynamically is that
it may be unknown how long the program will require a particular piece of data.

Funny, but I just started learning about this today. I am learning about storage classes, linkage, and scope.
A chunk of memory from the heap becomes completely inaccessible, and thus unrecoverable, when there are no more pointers to the chunk. (Either because the last pointer was assigned to point somewhere else, or simply vanished at the end of a function.) At this point, if a system has garbage collection, it will notice that the chunk of memory has been orphaned and make sure it is marked as available again. In a non-garbage collecting environment, like most C and C++ environments, allowing this to happen is what programmers call a "memory leak", i.e. usable memory is "leaking" out of your heap.
So THAT'S what a memory leak is! I never knew what that meant.
The mechanism to deal with this in standard C is a function called "free" (which should be detailed alongside malloc in your documentation). When finished with a dynamically allocated chunk of memory, you pass a pointer to the chunk as an argument to "free" and the chunk is returned to the heap.

While the C standard does not specify any facilities for garbage collection, there is no reason why a given compiler/development environment can't include one. It will, however, most likely be specific to that environment, so if it is important that your code be portable, it is a bad idea to rely on such a facility.

So you are saying for maximum portability, it's best that I do the memory management manually?

Thanks, plover. Your advice is always appreciated.

-Jessica
 
  • #26
Jessica,

At this point in your coding, don't worry about garbage collection yet -- you're not really even using any dynamic memory allocation. You should just use whatever development environment your university suggests that you use.

- Warren
 
  • #27
chroot said:
At this point in your coding, don't worry about garbage collection yet -- you're not really even using any dynamic memory allocation. You should just use whatever development environment your university suggests that you use.

Okie doke. I'll save that for later then. Ah, there's so much fun stuff to look forward to.. I think.. :rolleyes:

-Jessica
 
  • #28
Math Is Hard said:
That's very interesting. How big is a heap?
When a program starts up, it receives memory from the operating system. There needs to be enough memory for at least the following:
  • the executable code of the program
  • any global state defined by the program (i.e. global variables)
  • any hard coded data that was compiled into the executable
  • whatever local state is required by shared libraries
  • two empty sections for use by the run-time environment:
    1. a stack - the place where local state can be set up for each function that is called
    2. a heap - a pool from which to allocate memory
And here we reach the edge of what I can say with any certainty. The list above is a generalized list. All the things above are pretty much required for a program of any complexity, but how the memory is organized depends a great deal on what language and operating system is being used. I'm also not sure how the operating system decides how much extra space for the stack and heap to give a program at startup. In modern operating systems, there is usually no need to worry about how large these segments are as more space will be requested from the OS if it is necessary. (So, there's not much to worry about if you're not doing something with enormous memory requirements - e.g. large databases, or large scale scientific computation. Supercomputers these days can have hundreds of gigabytes of working memory.)

If I had to guess, I'd expect that a heap starts out at around 16k or so. Though I'm pretty sure there are ways to tell the compiler that a program requires a lot of memory, and thus that the OS should provide the space at startup.

So you are saying for maximum portability, it's best that I do the memory management manually?
Yes... :smile:
 
  • #29
well, a heap is a heap smaller than I thought it would be, I reckon!
 
  • #30
Well, you can tell I learned about computers a while ago... It turns out that Windows (98 & 2000 anyway) has a non-negotiable minimum of 1 megabyte for the heap. I haven't found anything documenting the process structure for Linux, so I'm not sure whether my guess is excessively low there or not. I assume with Linux there's a lot more freedom to tune things as one likes though. Also, my impression is that the overall philosophy behind Unix-like OSes is that running a lot of small, short processes shouldn't carry much overhead, so I wouldn't be surprised if I was closer to the mark for that kind of environment (then again I wouldn't be that surprised if I wasn't closer either... :wink:).

Another thing to keep in mind is that everything I'm talking about is just the most standard parts of memory management as specified by C. Any given OS will handle the parceling out memory to the various processes, and will have its own facilities for requesting memory and for setting up memory to be shared between processes. There is a standard set of "system calls" that accomplish this for Unix-like OSes; Windows, of course, has its own, entirely different set... :rolleyes:
 
Last edited:

FAQ: How can I declare an array of pointers to arrays of characters in C?

What is an array of pointers to arrays of characters in C?

An array of pointers to arrays of characters in C is a data structure that allows you to store multiple strings in a single variable. It is commonly used for storing and manipulating strings in C programming.

How do I declare an array of pointers to arrays of characters in C?

To declare an array of pointers to arrays of characters in C, you can use the following syntax: char *array_name[size]; where array_name is the name of your array and size is the number of strings you want to store.

How do I initialize an array of pointers to arrays of characters in C?

You can initialize an array of pointers to arrays of characters in C by assigning each element of the array to a string literal or a variable containing a string. For example: char *array_name[] = {"Hello", "World", "!"}; or char *array_name[] = {str1, str2, str3}; where str1, str2, and str3 are variables containing strings.

How do I access elements in an array of pointers to arrays of characters in C?

To access elements in an array of pointers to arrays of characters in C, you can use the array index notation. For example, to access the first string in the array, you can use array_name[0]. To access a specific character in a string, you can use the string index notation. For example, to access the third character in the first string, you can use array_name[0][2].

How do I free memory allocated for an array of pointers to arrays of characters in C?

To free memory allocated for an array of pointers to arrays of characters in C, you need to first free each individual string in the array using the free() function. Then, you can use the free() function again to free the memory allocated for the array itself. It is important to free memory in this order to avoid memory leaks.

Similar threads

Replies
23
Views
2K
Replies
3
Views
2K
Replies
8
Views
1K
Replies
2
Views
2K
Replies
32
Views
2K
Replies
6
Views
2K
Back
Top