#arrays #c #dynamic-memory-allocation
#массивы #c #динамическое выделение памяти
Вопрос:
У меня, по-видимому, трагическое понимание распределения памяти и массивов. То, что я хочу, довольно просто, есть массив массивов, массив содержит интервал внутри него. Мой вопрос в том, что, хотя я назначаю новый массив ниже int arr_letter[2] и присваиваю его arr[arr_index], на каждой итерации ВСЕ значения: arr[0], arr[1], arr[2] …. , присваиваются тому, что находится в arr[arr_index].
Я полагаю, что из-за того, как я объявил int * arr[26], мне понадобится аналогичный массив для интервала [x,y] каждый раз, когда я хочу добавить новый элемент в этот массив, вместо того, чтобы делать то, что я делаю, то есть перезаписывать массив. Но мне было интересно, есть ли у кого-нибудь лучший способ?
int * partitionLabels(char * S, int * returnSize)
{
int * arr[26];
memset(arr, 0, 26*sizeof(arr[0]));
int idx_start = 0;
int idx_end = 0;
int i = 0;
int j = 0;
while(S[i] != '')
{
// this populates all the intervals
// printf("%c %dn ", S[i], S[i]-97);
int arr_index = S[i]-97;
if(arr[arr_index] == 0)
{
// S[i]-97 is the integer representation of the character
idx_start = i;
idx_end = i;
j = i;
while(S[j] != '')
{
if(S[j] == S[i]) idx_end = j;
j ;
}
int arr_letter[2] = {idx_start, idx_end}; // problem is HERE
arr[arr_index] = arr_letter;
}
i ;
}
int main()
{
char * s = "ababcbacadefegdehijhklij";
int returnSize = 0;
partitionLabels(s, amp;returnSize);
}
Комментарии:
1. Вы знаете, что arr[26] и int arr_letter[2] допустимы только внутри partitionLabels(), верно? Также: Вопрос: является ли 26 хорошим «максимальным размером», или вы думаете, что вам может понадобиться больше 26? Если да, рассматривали ли вы просто создание связанного списка?
2. 26 — это хорошо. Я не буду возвращать arr[26] или arr_letter[2], однако они будут использоваться позже для returnSize . Мне просто нужен способ сгенерировать массив из 2 элементов, а затем назначить его arr[arr_index] . И что еще более важно, вылечите мое забытое понимание
3. Лично я бы просто объявил
int arr[2][26]
и объявил его вне «partitionLabels()».4. Я думаю, что проблема даже проще, чем вы думаете. это просто, когда я говорю «int arr_letter[2] = { … }», происходит то, что для переменной используется один и тот же адрес памяти, и arr назначит его всем элементам. Что мне нужно, так это уникальное назначение памяти для arr_letter[2] каждый раз, когда я его вызываю. Что заставляет меня думать, что лучше использовать другой указатель? lol …. мозговой туман (это действительно проблема новичка)
Ответ №1:
Проблема в том, что вы не используете выделение памяти. 🙂 Ваш arr
массив — это массив указателей на целые числа, но в нем нет места для хранения объявленных целых чисел. Когда вы это делаете int arr_letter[2] = {idx_start, idx_end}
, вы инициализируете автоматическую переменную в стеке со значениями idx_start
и idx_end
, а затем присваиваете текущему индексу in arr[]
. Но это значение, находящееся в стеке, является эфемерным. В худшем случае он не переживет область применения и в лучшем случае будет повторно использован на следующей итерации. Я бы рекомендовал, если я понимаю ваш вариант использования, объявить int arr[26][2]
, который выделяет два целых числа для каждого из 26 индексов в arr
. Тогда вы бы поставили arr[arr_index][1] = idx_start
и. arr[arr_index][2] = idx_end
(На самом деле, если бы это был я, я бы определил a struct interval { int start; int end };
, а затем создал массив из них, struct interval arr[26]
и arr[arr_index].start=idx_start
и arr[arr_index].end=idx_end
, но это может быть дальше, чем то, где вы находитесь.) Также, как кто-то указал, arr
исчезает, когда функция возвращается. Не уверен, как вы собираетесь получить к нему доступ.
Комментарии:
1. но, скажем, я действительно хотел использовать выделение памяти — похоже, memset не сделал то, что я думал, что это сделает для меня. Структура — хорошая идея.
2. Может быть. Что
memset
, по-вашему, сделал? Все, что он делает, это записывает нули в уже выделенную память.malloc
это то, что выделяет память.