You should assign an array of char pointers, and then, for each pointer assign enough memory for the string:
char **orderedIds;
orderedIds = malloc(variableNumberOfElements * sizeof(char*));
for (int i = 0; i < variableNumberOfElements; i++)
orderedIds[i] = malloc((ID_LEN+1) * sizeof(char)); // yeah, I know sizeof(char) is 1, but to make it clear...
Seems like a good way to me. Although you perform many mallocs, you clearly assign memory for a specific string, and you can free one block of memory without freeing the whole "string array"
Answer from MByD on Stack OverflowYou should assign an array of char pointers, and then, for each pointer assign enough memory for the string:
char **orderedIds;
orderedIds = malloc(variableNumberOfElements * sizeof(char*));
for (int i = 0; i < variableNumberOfElements; i++)
orderedIds[i] = malloc((ID_LEN+1) * sizeof(char)); // yeah, I know sizeof(char) is 1, but to make it clear...
Seems like a good way to me. Although you perform many mallocs, you clearly assign memory for a specific string, and you can free one block of memory without freeing the whole "string array"
char **orderIds;
orderIds = malloc(variableNumberOfElements * sizeof(char*));
for(int i = 0; i < variableNumberOfElements; i++) {
orderIds[i] = malloc((ID_LEN + 1) * sizeof(char));
strcpy(orderIds[i], your_string[i]);
}
Videos
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
You know from the start you will have number strings to store so you will need an array of size number to store a pointer to each string.
You can use malloc to dynamically allocate enough memory for number char pointers:
char** strings = malloc(number * sizeof(char*));
Now you can loop number times and allocate each string dynamically:
for (int i = 0; i < number; i++) {
// Get length of string
printf("Enter the length of string %d: ", i);
int length = 0;
scanf("%d", &length);
// Clear stdin for next input
int c = getchar(); while (c != '\n' && c != EOF) c = getchar();
// Allocate "length" characters and read in string
printf("Please enter string %d: ", i);
strings[i] = malloc(length * sizeof(char));
fgets(strings[i], length, stdin);
}
Since you want to save both the length and the string, I'll suggest that you put them together in a struct. Like
struct string
{
int length;
char* str;
};
Now you can dynamically create an array of this struct and dynamically assign memory for the individual strings.
Something like:
#include <stdio.h>
#include <stdlib.h>
struct string
{
int length;
char* str;
};
int main(void) {
int i;
char tmp[128];
int number = 3;
struct string* strings = malloc(number * sizeof *strings);
// read the input
for (i=0; i<number; ++i)
{
printf("length?\n");
if (fgets(tmp, sizeof tmp, stdin) == NULL)
{
printf("error 1");
exit(1);
}
int length;
if (sscanf(tmp, "%d", &length) != 1)
{
printf("error 2");
exit(1);
}
strings[i].length = length;
strings[i].str = calloc(length + 2, 1);
printf("string?\n");
if (fgets(strings[i].str, length + 2, stdin) == NULL)
{
printf("error 3");
exit(1);
}
if (strings[i].str[length] != '\n')
{
printf("error 4");
exit(1);
}
strings[i].str[length] = '\0';
}
// print the strings
for (i=0; i<number; ++i)
{
printf("len=%d str=%s\n", strings[i].length, strings[i].str);
}
// Clean up, i.e. free the memory allocated
for (i=0; i<number; ++i)
{
free(strings[i].str);
}
free(strings);
return 0;
}
Note: You should also check that all malloc/calloc are succesful, i.e. doesn't return NULL. For clarity I skipped that.
I've been given the task of reading words into an array and then running insertion sort on them. The way it has been set out to do this is by using an array of char pointers and then assigning memory to each index in order to store a string. The code for that is already in place. But I just don't understand how using malloc makes space for a sting within a char? I'm honestly not even sure if what I just wrote makes sense. Pointers are frying my brain. Any help would be much appreciated. I've done a fair bit of Java before if that helps any explaination .
You cannot store an array of strings in C, as a string is a variable-length datastructure, not a simple type.
So, decide what you want:
An array of fixed-length buffers storing strings of fixed (maximum) length.
char (*p)[MAX_LEN] = malloc(n * sizeof *p); // Store the strings at p[0], p[1], …, p[n - 1]A buffer storing any number of strings consecutively.
char* p = malloc(sum_of_string_lengths + count_of_strings); // Now fill in the strings one after the other, including TerminatorAn array of pointers to strings.
char** p = malloc(n * sizeof *p); p[0] = strdup(source[0]); // ... // p[n - 1] = ...With
strdup()the common utility-function defined like:char* strdup(const char* s) { size_t n = strlen(s) + 1; char* r = malloc(n); if (r) memcpy(r, s, n); return r; }
You've declared argumentArray as a two-dimensional array of char. The malloc function returns a pointer, so you can't assign a pointer to an element of this array.
You need a pointer to store what's being returned. Actually, in this case you need a pointer to a pointer, and you'll need to call malloc multiple times, once for an array of pointers for the arguments, then again in a loop for each argument:
char **argumentArray = malloc(MAX_NUM_OF_ARGS * sizeof(char *));
for (int i=0; i<MAX_NUM_OF_ARGS; i++) {
argumentArray[i] = malloc(MAX_ARG_SIZE);
strcpy(argumentArray[i], defaultArgs);
printf("%s\n", argumentArray[i]);
}
I think you need to try and understand yourself what you are trying to achieve. You don't need the key[2] array and I think you are confusing yourself there as you don't yet understand how pointers work. The following should work (untested)
// Allow a password up to 99 characters long + room for null char
char password[100];
// pointer to malloc storage for password
char *key;
int textlen, keylen, i, j, k, t, s = 0;
// Prompt user for password
printf("password:\n") ;
scanf("%s",password);
// Determine the length of the users password, including null character room
keylen = strlen(password) + 1;
// Copy password into dynamically allocated storage
key = (char*)malloc(keylen * sizeof(char));
strcpy(key, password);
// Print the password
printf("The key is:\n\t %s", key);
The problem that you have is here:
printf("The key is:\n\t %s", key);
You are passing the pointer array to printf, while what you would want to do is
printf("The key is:\n\t %s", key[0]);
Yet another problem is that you allocte as much pointers as you have characters in your password, so you overwrite the pointer array you reserved, because key has only room for two pointers, not for N, which is the primary cause for your "bad pointer" problem.
And another thing, which is not related to this error is, that you shouldn't cast malloc as well as you don't need to multiply with sizeof(char) as this will always be 1 by definition.
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.
You want to allocate an array of strings, in other words an array of pointers to characters, and that's exactly what you do allocate. The problem is that you assign the pointer returned by calloc to an array of characters.
You have two choices here actually: Either change your declaration of array to be an "array" pointers to character, e.g. char **array, and then dynamically allocate the individual strings as well. Something like this
// Allocate an array of pointers
char **array = calloc(N, sizeof(*array));
// Allocate and read all strings
for (size_t i = 0; i < N; ++i)
{
// Allocate 50 characters
array[i] = malloc(50); // No need for `sizeof(char)`, it's always 1
// Read up to 49 characters (to leave space for the string terminator)
scanf("%49s", array[i]);
}
Or you can change the type of array, to be a pointer to fixed-sized "strings", like this
// Define `my_string_type` as an array of 50 characters
typedef char my_string_type[50];
// Declare a pointer to strings, and allocate it
my_string_type *array = calloc(N, sizeof(*array));
// Read all strings from the user
for (size_t i = 0; i < N; ++i)
{
// Read up to 49 characters (to leave space for the string terminator)
scanf("%49s", array[i]);
}
Note that I don't cast the result of calloc or malloc. You should never cast void * in C.
In the scanf function, you need to select a format and the array you want the data to go. For example:
scanf("%[^\n]", array);