NOTE: My examples are not checking for NULL returns from malloc()... you really should do that though; you will crash if you try to use a NULL pointer.
First you have to create an array of char pointers, one for each string (char *):
char **array = malloc(totalstrings * sizeof(char *));
Next you need to allocate space for each string:
int i;
for (i = 0; i < totalstrings; ++i) {
array[i] = (char *)malloc(stringsize+1);
}
When you're done using the array, you must remember to free() each of the pointers you've allocated. That is, loop through the array calling free() on each of its elements, and finally free(array) as well.
NOTE: My examples are not checking for NULL returns from malloc()... you really should do that though; you will crash if you try to use a NULL pointer.
First you have to create an array of char pointers, one for each string (char *):
char **array = malloc(totalstrings * sizeof(char *));
Next you need to allocate space for each string:
int i;
for (i = 0; i < totalstrings; ++i) {
array[i] = (char *)malloc(stringsize+1);
}
When you're done using the array, you must remember to free() each of the pointers you've allocated. That is, loop through the array calling free() on each of its elements, and finally free(array) as well.
The common idiom for allocating an N by M array of any type T is
T **a = malloc(N * sizeof *a);
if (a)
for (i = 0; i < N; i++)
a[i] = malloc(M * sizeof *a[i]);
As of the 1989 standard, you don't need to cast the result of malloc, and in fact doing so is considered bad practice (it can suppress a useful diagnostic if you forget to include stdlib.h or otherwise don't have a prototype for malloc in scope). Earlier versions of C had malloc return char *, so the cast was necessary, but the odds of you having to work with a pre-1989 compiler are pretty remote at this point. C++ does require the cast, but if you're writing C++ you should be using the new operator.
Secondly, note that I'm applying the sizeof operator to the object being allocated; the type of the expression *a is T *, and the type of *a[i] is T (where in your case, T == char). This way you don't have to worry about keeping the sizeof expression in sync with the type of the object being allocated. IOW, if you decide to use wchar instead of char, you only need to make that change in one place.
c - How to dynamically allocate memory space for a string and get that string from user? - Stack Overflow
c - dynamic memory allocation for strings - Stack Overflow
c - Dynamic memory allocation for pointer arrays - Stack Overflow
c - Using Dynamic Memory allocation for arrays - Stack Overflow
Videos
The problem is this:
scanf("%s", &table[i]);
and this:
printf("Person nr %d : %s ", i+1, &table[i]);
You seem to forget that table[i] is a pointer to char which is what a string basically is. By using &table[i] you get a pointer to the pointer, which is of type char **. You basically treat the pointer itself as a string, not the memory it points to.
Simply drop the address-of operator and you can read strings up to five characters (plus the terminator).
&table[i] is of the type char** and table[i] is the type char*.
table[i] is the pointer for your string.
You should change the &table[i] to table[i].
Read one character at a time (using getc(stdin)) and grow the string (realloc) as you go.
Here's a function I wrote some time ago. Note it's intended only for text input.
char *getln()
{
char *line = NULL, *tmp = NULL;
size_t size = 0, index = 0;
int ch = EOF;
while (ch) {
ch = getc(stdin);
/* Check if we need to stop. */
if (ch == EOF || ch == '\n')
ch = 0;
/* Check if we need to expand. */
if (size <= index) {
size += CHUNK;
tmp = realloc(line, size);
if (!tmp) {
free(line);
line = NULL;
break;
}
line = tmp;
}
/* Actually store the thing. */
line[index++] = ch;
}
return line;
}
You could have an array that starts out with 10 elements. Read input character by character. If it goes over, realloc another 5 more. Not the best, but then you can free the other space later.
just add getchar() after scanf()
so that each '\n' gets disposed of while taking input.
Your code will be
int ReadNames(char ***Names, int *n)
{
int i, k;
char name[100];
printf("Enter how many names\n");
scanf("%d", n);
getchar(); // eats unnecessary '\n' in the buffer
/* Allocate memory and read names */
*Names=(char **)malloc((*n)*sizeof(char *));
for(i=0;i<(*n);i++)
{
*(*Names+i)=(char*)malloc(sizeof(name));
gets(name);
strcpy(*(*Names+i),name);
}
for(i=0;i<(*n);i++)
printf("%s\n",*(*Names+i));
return 1;
}
void main()
{
char **Names;
int n, i;
ReadNames(&Names, &n);
}
The problem you are having is most likely because the scanf you use to get the count leaves the newline still in the buffer. This means that the first gets call reads that single newline and you add that empty line.
A simple and easy solution is to add a space after the scanf format, which tells scanf to skip all whitespace. Like
scanf("%d ", n);
In C a string is a char*. A dynamic array of type T is represented as a pointer to T, so for char* that would be char**, not simply a char* the way you declared it.
The compiler, no doubt, has issued some warnings about it. Pay attention to these warnings, very often they help you understand what to do.
Here is how you can start your testing:
char **aPtr;
int len = 1; // Start with 1 string
aPtr = malloc(sizeof(char*) * len); // Do not cast malloc in C
aPtr[0] = "This is a test";
printf("%s",aPtr[0]); // This should work now.
char *str; //single pointer
With this you can store one string.
To store array of strings you Need two dimensional character array
or else array of character pointers or else double pointer
char str[10][50]; //two dimensional character array
If you declare like this you need not allocate memory as this is static declaration
char *str[10]; //array of pointers
Here you need to allocate memory for each pointer
loop through array to allocate memory for each pointer
for(i=0;i<10;i++)
str[i]=malloc(SIZE);
char **str; //double pointer
Here you need to allocate memory for Number of pointers and then allocate memory for each pointer .
str=malloc( sizeof(char *)*10);
And then loop through array allocate memory for each pointer
for(i=0;i<10;i++)
str[i]=malloc(SIZE);
You use pointers.
Specifically, you use a pointer to an address, and using a standard c library function calls, you ask the operating system to expand the heap to allow you to store what you need to.
Now, it might refuse, which you will need to handle.
The next question becomes - how do you ask for a 2D array? Well, you ask for an array of pointers, and then expand each pointer.
As an example, consider this:
int i = 0;
char** words;
words = malloc((num_words)*sizeof(char*));
if ( words == NULL )
{
/* we have a problem */
printf("Error: out of memory.\n");
return;
}
for ( i=0; i<num_words; i++ )
{
words[i] = malloc((word_size+1)*sizeof(char));
if ( words[i] == NULL )
{
/* problem */
break;
}
}
if ( i != num_words )
{
/* it didn't allocate */
}
This gets you a two-dimensional array, where each element words[i] can have a different size, determinable at run time, just as the number of words is.
You will need to free() all of the resultant memory by looping over the array when you're done with it:
for ( i = 0; i < num_words; i++ )
{
free(words[i]);
}
free(words);
If you don't, you'll create a memory leak.
You could also use calloc. The difference is in calling convention and effect - calloc initialises all the memory to 0 whereas malloc does not.
If you need to resize at runtime, use realloc.
- Malloc
- Calloc
- Realloc
- Free
Also, important, watch out for the word_size+1 that I have used. Strings in C are zero-terminated and this takes an extra character which you need to account for. To ensure I remember this, I usually set the size of the variable word_size to whatever the size of the word should be (the length of the string as I expect) and explicitly leave the +1 in the malloc for the zero. Then I know that the allocated buffer can take a string of word_size characters. Not doing this is also fine - I just do it because I like to explicitly account for the zero in an obvious way.
There is also a downside to this approach - I've explicitly seen this as a shipped bug recently. Notice I wrote (word_size+1)*sizeof(type) - imagine however that I had written word_size*sizeof(type)+1. For sizeof(type)=1 these are the same thing but Windows uses wchar_t very frequently - and in this case you'll reserve one byte for your last zero rather than two - and they are zero-terminated elements of type type, not single zero bytes. This means you'll overrun on read and write.
Addendum: do it whichever way you like, just watch out for those zero terminators if you're going to pass the buffer to something that relies on them.
While Ninefingers provided an answer using an array of pointers , you can also use an array of arrays as long as the inner array's size is a constant expression. The code for this is simpler.
char (*words)[15]; // 'words' is pointer to char[15]
words = malloc (num_words * sizeof(char[15]);
// to access character i of word w
words[w][i];
free(words);
Okay so basically I have a function that takes in a string and counts the lowercase tokens in it. I need to make a function that then returns an array of the lowercase tokens. I would need to use malloc to allocate enough memory for such array but I donโt know how to go about doing so.
Once the array is allocated how would I put the token strings into the array?
Any help is appreciated thank you
First you need to understand the difference between the following three declarations. For the sake of brevity, assume N is MAX_WORD_LEN+1 to match your sizing:
char data[N]; // array of N chars
char *data[N]; // array of N char *pointers* (i.e. char *)
char (*data)[N]; // pointer to array of N chars
Remember above all else, pointers are variables that hold an "address" and are implementation-defined. Just like an int variable holds the value of an implementation integer, a pointer variable holds an implementation address.
In almost all cases, you can properly malloc() memory for a pointer type using the sizeof() operator with the underlying target dereferenced. There are some cases where this is not intuitive or easily presentable, but the following should help:
// allocates sizeof(Type) block
Type *p = malloc(sizeof(*p));
// allocates N*sizeof(Type) contiguous blocks
// note: we'll use this style later to answer your question
Type *pa = malloc(N * sizeof(*pa));
This will work no matter what Type is. This is important, because in your case you have a pointer declared as :
char (*dict)[N];
As we already discussed above, this declares a pointer of type (pointer-to-N-chars). Note that no actual memory has been allocated yet. This is just a pointer; nothing more. Therefore, you can safely allocate a single element using the above syntax as:
// allocate single block
char (*dict)[N] = malloc(sizeof(*dict));
But this only accounts for a single entry. You need len entries, so :
// allocate 'len' contiguous blocks each N chars in size
char (*dict)[N] = malloc(len * sizeof(*dict));
Now dict is safely addressable as an array from 0..(len-1). You can copy in your data such as:
strcpy(data[0], "test");
strcpy(data[1], "another test");
So long as the source string does not exceed N-chars (including the zero-terminator), this will work correctly.
Finally, don't forget to free your allocation when finished:
free(dict);
Spoiler
myDict->dict0 = malloc( myDict->len * sizeof(*(myDict->dict0)));
myDict->dict1 = malloc( myDict->len * sizeof(*(myDict->dict1)));
In the declaration of the structure,
char (*dict0)[MAX_WORD_LEN+1];
means that dict0 is a pointer to a character array of MAX_WORD_LEN + 1 elements i.e. char [11].
To initialize the field of your object, you can consider an example as shown below
void createDict(struct dict* myDict)
{
myDict->dict0 = &glbarr;
myDict->dict1 = &glbarr;
}
where glbarr is a global array defined as
char glbarr[MAX_WORD_LEN+1];
So lets say i do int x=5; so i create a variable of 4 bytes that stores a value of 5
then i do int *y= malloc(sizeof(int)); here i created a pointer that gave me a memory location in the RAM and i can do *y=5; to store 5 in it. What exactly is the benefit of using dynamic allocation here?
plus in case of strings how do i dynamically allocate just enough memory to store name of some guy in c without knowing it before hand how long the name is?
like char name[4]; means i have an array of 5 char out of which im supposed to use 4. But here i need to make sure name is of length 4 always.
but char *name = malloc(5*sizeof(char)); dynamically allocates the same memory but i still need to make sure length of name stays 4 plus one extra for the null.
how is this implemented to take values of any length?