#c
#c
Вопрос:
Если у меня есть количество элементов в переменной с именем «totalstrings» и переменная с именем «размер строки», которая является размером строки каждого элемента, как мне динамически выделить массив с именем «массив»?
Это массив строк на C, а не на C .
Спасибо!
Комментарии:
1. Это зависит от того, что вы, возможно, пробовали, а что не сработало.
2. И, конечно, почему вы думаете, что это не сработало.
Ответ №1:
ПРИМЕЧАНИЕ: мои примеры не проверяют нулевые возвраты из malloc() … вам действительно следует это сделать; вы потерпите крах, если попытаетесь использовать нулевой указатель.
Сначала вам нужно создать массив указателей символов, по одному для каждой строки (char *):
char **array = malloc(totalstrings * sizeof(char *));
Далее вам нужно выделить место для каждой строки:
int i;
for (i = 0; i < totalstrings; i) {
array[i] = (char *)malloc(stringsize 1);
}
Когда вы закончите использовать массив, вы должны запомнить free()
каждый из выделенных вами указателей. То есть перебирать массив, вызывая free()
каждый из его элементов, и, наконец free(array)
, также.
Комментарии:
1. Но
malloc
возврат NULL обычно является слишком серьезной ошибкой, чтобы продолжать, в любом случае. Мы же не хотим быть чрезмерно параноидальными, не так ли? И что действительно неправильно, так это приведениеmalloc
возвращаемого значения, которое в C совершенно не нужно и обычно является плохой практикой (но неважно, я тоже из C -фона). В противном случае хороший ответ. 1 для правильногоfree
запоминания.2. Действительно, в C приведение результата malloc может быть опасным, если кто-то забудет включить <stdlib.h> . Хороший ответ в противном случае.
3. Что, если каждая строка имеет разный размер, скажем, я пытаюсь сохранить список имен
4. @Aadishri это не проблема; вам не нужно, чтобы каждая строка malloc была одинакового размера, вы можете изменять их размер по своему усмотрению.
5. @sivaram для начала у вас должно быть хотя бы начальное количество строк, и вы захотите сохранить переменную с текущим размером вашего массива. Если вам позже понадобится расширить пространство, вы можете
realloc()
увеличить свой массив до большего размера.
Ответ №2:
Общая идиома для выделения массива N на M любого типа T:
T **a = malloc(N * sizeof *a);
if (a)
for (i = 0; i < N; i )
a[i] = malloc(M * sizeof *a[i]);
Начиная со стандарта 1989 года, вам не нужно приводить результат malloc
, и фактически это считается плохой практикой (это может подавить полезную диагностику, если вы забудете включить stdlib.h или иным образом не имеете прототипа для malloc
in scope). Более ранние версии C malloc
возвращали char *
возврат, поэтому приведение было необходимо, но вероятность того, что вам придется работать с компилятором до 1989 года, на данный момент довольно мала. C требует приведения, но если вы пишете C , вы должны использовать new
оператор.
Во-вторых, обратите внимание, что я применяю sizeof
оператор к выделяемому объекту; тип выражения *a
равен T *
, а тип *a[i]
равен T
(где в вашем случае T
== char
). Таким образом, вам не нужно беспокоиться о синхронизации sizeof
выражения с типом выделяемого объекта. Итак, если вы решите использовать wchar
вместо char
, вам нужно внести это изменение только в одном месте.
Ответ №3:
char** stringList = (char**)malloc(totalStrings * sizeof(char*));
for( i=0; i<totalStrings; i ) {
stringList[i] = (char*)malloc(stringSize[i] 1);
}
Ответ №4:
Я знаю, что этот вопрос старый и на него уже был дан ответ. Я просто хочу указать, что malloc
это системный вызов, и его не следует использовать несколько раз.
Было бы лучше выделить один большой кусок памяти и сделать так, чтобы массив указывал на него. Что-то вроде этого :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STR_SIZE 100 //STR_SIZE doesn't have to be a constant
int main(){
int i;
char **arr;
char *long_string;
long_string = (char *)malloc(sizeof(char)*STR_SIZE*10);
arr = malloc(sizeof(char *)*10);
//Pointing each item of the array to an allocated memory.
for (i=0; i<10; i ){
arr[i] = (long_string STR_SIZE * i);
}
//Initialising the array
for (i=0; i<10; i ){
strcpy(arr[i], "This is a line in a
paragraphn");
}
//Printing the items of the array
for (i=0; i<10; i ){
printf("%s n", arr[i]);
}
//freeing the allocated memory
free(long_string);
free(arr);
return 0;
}
Ответ №5:
Ну, сначала вы можете выделить место для «массива», который будет представлять собой массив символов * длиной «totalstrings».
Какими тогда будут начальный и конечный индексы в «массиве»? Вы знаете, что первый равен 0; какой последний?
Затем для каждой записи в «массиве» вы могли бы (если хотите) выделить одну область памяти, которая равна «stringsize 1» (почему 1, скажите, пожалуйста?) длинный, вводящий начальный адрес этой области — этой строки — в правильный элемент «массива».
Это было бы хорошим началом, imo.