Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Stim24
Зарегистрирован: 16.01.2006 Сообщения: 6
|
Добавлено: Вт Фев 21 2006 06:47 Заголовок сообщения: проблемма с массивами |
|
|
Нужно сделать
void f(void **k) // Ф-ция создает массива и и заносит значение
{int ll=5;
k=new int(ll);
for(int i=0;i<ll;i++)
{
k[i]=i;
}
}
void main()
{
int *k; //создали указатель
f(&k); // вызвали ф-цию.. в которой создалися массив
//с массивом работаем
for(int i=0;i<5;i++)
{
printf("%d /n",k[i]);
}
}
Вообщем мне нужно создать массив одномерный как я понимаю он создаеться
k=new int[N] но мне его нужно создать в ф-ции и вернуть его как это реализовать подскажите? _________________ умом Россию не понять |
|
Вернуться к началу |
|
|
GREA
Зарегистрирован: 14.05.2003 Сообщения: 758 Откуда: Новосибирск
|
Добавлено: Вт Фев 21 2006 22:39 Заголовок сообщения: |
|
|
int *f()
{....
k=new int[N];
....
return k;
} |
|
Вернуться к началу |
|
|
kolobok0
Зарегистрирован: 22.04.2005 Сообщения: 253 Откуда: Мсква
|
Добавлено: Вс Фев 26 2006 14:33 Заголовок сообщения: Re: проблемма с массивами |
|
|
Stim24 писал(а): | .... но мне его нужно создать в ф-ции и вернуть его как это реализовать подскажите? |
во всех учебниках по сям Вы найдёте рекомендации инкапсулировать данные и их обработку. В си плас плас этот взгляд на весчи вошёл в парадигму самого языка.
То, что Вы предлагаете (спрашиваете) идёт в разрез этих рекомендаций. Что чревато может сказаться в больших системах...На этот счёт написано много - поищите, почитайте.
Как решение Вашей проблемы - либо вынести аллокацию из функции, либо инкапсулировать работу с данными масивом внутри файла (си), класса (си плас плас). Т.е. его "распечатку" произвести так же внутри данного файла. Указатель (или даже сам массив) сделать статическим. Либо делегировать коду, который контроллирует и знает всё об этих данных - указатель на функцию обработчик "распечатки". Последний вариант более элегантный в стиле си...
То, что предложил товарисч Выше (из новосиба) - ТИПИЧНАЯ ОШИБКА в программировании. НЕ рекомендую делать так !
с уважением
(круглый) |
|
Вернуться к началу |
|
|
GREA
Зарегистрирован: 14.05.2003 Сообщения: 758 Откуда: Новосибирск
|
Добавлено: Вт Фев 28 2006 00:54 Заголовок сообщения: |
|
|
Цитата: | То, что предложил товарисч Выше (из новосиба) - ТИПИЧНАЯ ОШИБКА в программировании. НЕ рекомендую делать так ! |
То что предложил точварсч из Новосиба - было конкретным ответом на конкретный вопрос. Вроде бы именно это и спрашивали.
И для сдачи лабораторной вполне сойдет (классы, я полагаю, они будут проходить позже по программе)
Пример:
Код: |
#include<stdio.h>
int *f()
{int *k;
k=new int[10];
k[0]=0;
k[1]=1;
k[2]=2;
k[3]=3;
k[4]=4;
k[5]=5;
k[6]=6;
k[7]=7;
k[8]=8;
k[9]=9;
return k;
}
int main(void)
{int *s;
s=f();
for(int i=0;i<10;i++)printf("%d ",s[i]);
return 0;
} |
|
|
Вернуться к началу |
|
|
kolobok0
Зарегистрирован: 22.04.2005 Сообщения: 253 Откуда: Мсква
|
Добавлено: Вт Фев 28 2006 19:24 Заголовок сообщения: |
|
|
GREA писал(а): | ...То что предложил точварсч из Новосиба - было конкретным ответом на конкретный вопрос. Вроде бы именно это и спрашивали. И для сдачи лабораторной вполне сойдет (классы, я полагаю, они будут проходить позже по программе).... |
Да, конкретный...
Так же конкретный - выключить комп...выпить яду и прочая муть...
Хотя если стоит лишь бы сделать и научиться плохому - то да катит. Ышо раз повторюсь - пример ПЛОХОЙ. Из разряда как НЕ НАДО. Боюсь и само задание, либо не понято человеку до конца - либо содержит подвох по данной тематике.
что за дурацкая манера прослеживается в форумах - лишь бы ляпнуть ?
Либо дали более развёрнутый ответ:
- "первое, что пришло на ум, но содержит те и те ошибки"...
с уважением
(круглый)
ЗЫ
Более того - это ТИПИЧНЫЙ пример на собеседовании практически любой фирмы. Потому как при производстве софта - не дай бог попадётся человек с оценкой данного подхода - но это же сойдёт, не корабли же запускаем в космос !
ЗЫ ЗЫ
Более того пример настолько христаматийный - что найдёте практически в любом учебники по сям с обсасыванием - почему так низзя...даже обсуждать нечего... прописные истины глаголю...дожил... |
|
Вернуться к началу |
|
|
GREA
Зарегистрирован: 14.05.2003 Сообщения: 758 Откуда: Новосибирск
|
Добавлено: Ср Мар 01 2006 00:11 Заголовок сообщения: |
|
|
Колобок, Вместо того, чтобы пространно рассуждать, как не надо, лучше бы привел человеку пример, как следует делать. Конкретно к его задаче. А гневно трясти воздух ИМХО бессмысленно. И полагаю, Stim24, не за этим на форум обратился чтобы получить ликбез по общей теории искусства программирования. Если он обратился с таким вопросом к нам на форум, мне думается у него явный дефицит времени. А ты его отсылаешь читать книжки по классам и т.п.
А что касается стиля... Каюсь, когда сам сдавал лабы, то вместо быстрых сортировок постоянно использовал банальный пузырек. Ну и что? Можно еще верификацию каждого подалгоритма проводить. Оптимизировать и вычищать до бесконечности... и вылететь с долгами (предчувствую очередную гневную тираду )
(Stim24, если я не прав, поправь меня) |
|
Вернуться к началу |
|
|
kolobok0
Зарегистрирован: 22.04.2005 Сообщения: 253 Откуда: Мсква
|
Добавлено: Ср Мар 01 2006 14:29 Заголовок сообщения: |
|
|
GREA писал(а): | Колобок, Вместо того, чтобы пространно рассуждать, как не надо, лучше бы привел человеку пример, как следует делать. Конкретно к его задаче. ........ |
уже писал Выше...
повторяю...
"Как решение Вашей проблемы - либо вынести аллокацию из функции, либо инкапсулировать работу с данными масивом внутри файла (си), класса (си плас плас). Т.е. его "распечатку" произвести так же внутри данного файла. Указатель (или даже сам массив) сделать статическим. Либо делегировать коду, который контроллирует и знает всё об этих данных - указатель на функцию обработчик "распечатки". Последний вариант более элегантный в стиле си... "
какая фраза или слово Вам не понятно ?
Или предлагается написать за человека код ?
с уважением
(круглый) |
|
Вернуться к началу |
|
|
GREA
Зарегистрирован: 14.05.2003 Сообщения: 758 Откуда: Новосибирск
|
Добавлено: Ср Мар 01 2006 21:43 Заголовок сообщения: |
|
|
мне понятно все.
А вот тому, кто спрашивал - не знаю. |
|
Вернуться к началу |
|
|
Aragaer
Зарегистрирован: 28.03.2005 Сообщения: 164
|
Добавлено: Чт Мар 02 2006 10:41 Заголовок сообщения: |
|
|
Абсолютно не могу понять, в чем тут проблема. Почему мы не имеем права сделать примерно так:
Код: | int *my_alloc_and_fill(int N) {
int k[N];
for(int i=0; i<N; i++)
k[i]=i
return k
} | а снаружи соответственно вызвать int *array = my_alloc_and_fill(100)
Чесслово, не вижу никаких проблем, которые мог бы повлечь за собой такой код. Или сказывается мой недостаток опыта над крупными проектами?
Да, разумеется, вывод содержимого такого массива я бы тоже огрызовал в виде подпрограммы my_print, а удаление - my_erase. Так, на всякий случай. _________________ Open your eyes.
And Awaken. |
|
Вернуться к началу |
|
|
kolobok0
Зарегистрирован: 22.04.2005 Сообщения: 253 Откуда: Мсква
|
Добавлено: Чт Мар 02 2006 13:59 Заголовок сообщения: |
|
|
Aragaer писал(а): | Абсолютно не могу понять, в чем тут проблема. ... |
данный пример ышо хуже...сразу видно, что автор слабо представляет что такое стэк, время жизни переменных, физическое устройство стэка, как проц работает со стэком...
если Вы изучите эти вопросы, то найдёте много для себя интересного...мне так каеться...
с уважением
(круглый)
ЗЫ
На мой взгляд - корень этих подходов один... А именно - упование на свой гений, память, добрую волю других разработчиков (даже не волю, а однотипность мышления)..Что являеться в корне НЕ верно...
ЗЫ ЗЫ
Как и в первом примере достаточно Ваши указатели передать фиг знает куда и привет семье...Поиск типа работает, то нет...Или Почему под отладчиком всё круто а в релизе нет ? Или ышо хуже..На этой тачке работает - на той нет...
ЗЫ ЗЫ ЗЫ
Код(последний) вообще может отказаться работать на классе защиты C2 (если щаз не подводит память - это там, где после освобождения памяти она ЗАТИРАЕТСЯ. Стэк - точно такая же память...) |
|
Вернуться к началу |
|
|
Aragaer
Зарегистрирован: 28.03.2005 Сообщения: 164
|
Добавлено: Пт Мар 03 2006 02:58 Заголовок сообщения: |
|
|
Странно, но вот в ядре Линукса подобный код как раз встречается на каждом шагу. Разве что вместо int k[N] было бы что-то вроде
int *k = kmalloc(N*sizeof(int)), может в этом загвоздка?
И по-моему тут вообще нет никакого освобождения памяти. Освобождать память мы будем руками - free(array).
(Сейчас продискутировал со своим внутренним голосом и пришел к выводу, что создание массива через маллок принципиально отличается от того, что делается в моем примере. Область видимости статического массива действительно ограничивается блоком, как бы мы ни пытались воевать со ссылками. Демонический же массив гораздо больше похож на то, чем я жонглировал в ядре.) _________________ Open your eyes.
And Awaken. |
|
Вернуться к началу |
|
|
kolobok0
Зарегистрирован: 22.04.2005 Сообщения: 253 Откуда: Мсква
|
Добавлено: Пт Мар 03 2006 14:40 Заголовок сообщения: |
|
|
Aragaer писал(а): | Странно, но вот в ядре Линукса подобный код как раз встречается на каждом шагу. Разве что вместо int k[N] было бы что-то вроде
int *k = kmalloc(N*sizeof(int)), может в этом загвоздка?
... |
конечно же есть различие...обращение к менэджеру памяти - это выделение куска не из стэка....а из пула...но тут есть одна тонкость...о ней я сказал выше...
не хорошо (в умных книгах обьясняется почему, тут я это опущу) - выделять память в "одном" месте а грохать в "другом".. Посему в классах инкапсулируют (стараются) эти шаги - внутри класса.. А в сях - внутри файла (модуля)....А это значит, что указатель не стоит хранить на стэке - это потенциальная ошибка (имееться ввиду не любого указателя, а в рамках той задачи, что прозвучала в оригинальном посте)... Хранение локально как статический параметр - так же не отследит Вам автоматом освобождение памяти например..НО ! Это ПОДЧЁРКИВАЕТ политику работы с ним... Т.е. Вы должны будете предпологать, что он может быть проинициализирован, а может и нет... Соответственно нуна это обрабатывать и т.д..
Другими словами - не стоит передавать из меньшего (подпрограммы) в большее(куска который вызвал подпрограмму) аллокированную память (тем более выделенную на стэке). Лучше в таком случае - сделать указатель на неё как статический и обрабатывать соответствующим образом...Т.е. начальная инициализация - нулём.. При очистке - освобождение и запись нуля... При начале любого доступа - проверка на ноль и если да, то вызов инициализации...Ну и т.п...
с уважением
(круглый) |
|
Вернуться к началу |
|
|
Aragaer
Зарегистрирован: 28.03.2005 Сообщения: 164
|
Добавлено: Пт Мар 03 2006 16:21 Заголовок сообщения: |
|
|
Инициализация нулем - это разумеется. И разумеется в многопоточных программах там все эти фокусы будут перекрываться разными средствами синхронизации.
То есть (уже не применительно к описанной задаче, а в более правильном виде) это должно быть огрызовано примерно так:
Код: | int my_alloc_and_fill (int **p, int N) {
if(*p)
return -1;
*p = malloc(N*sizeof(int));
if(! *p)
return -1;
for(int i; i<N; i++)
*p[i] = i;
return 0;
} | и вызывать эту штуку через
Код: | int *k = NULL;
if (my_alloc_and_fill(&k, 100)) {
printf("Не удалось выделить память");
exit(1);
} | Ну или еще как упростить. Очистка массива в виде примерно такой же подпрограммы, причем все они в пределах одного модуля.
Я правильно все описал? _________________ Open your eyes.
And Awaken. |
|
Вернуться к началу |
|
|
|