Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Динамические массивы в С++

2.1K
15 июля 2009 года
smoki
115 / / 05.11.2006
Здравствуйте, у меня к Вам вопрос про динамические массивы. Если у нас заранее не известно сколько байт нужно выделить под массив, то как лучше инициализировать массив:

Первый способ
 
Код:
.....
i=0;
do
{
 mas = (int *)malloc(2);
 mas = random(40);
 i++;
}
while();
.......


Второй способ
Код:
.....
i=0;
mas = (int *)malloc(2);
do
{
 mas = random(40);
 mas=(int *)realloc(mas,i*2);
 i++
}
while();
.......


Эти два кода равнозначны?
9
15 июля 2009 года
Lerkin
3.0K / / 25.03.2003
Цитата: smoki

...
Эти два кода равнозначны?


Сам-то как думаешь?

И еще: объясни, что хотел сделать-то? Глядя на две эти глупости, понять цель невозможно.

2.1K
15 июля 2009 года
smoki
115 / / 05.11.2006
Я просто пытаюсь разобраться с динамическими массивами, смотрите такая ситуация: нужно подсчитать количество символов введенных с клавиатуры(те примеры не относятся к этой задачи).
В этом случае мы не знаем сколько символов будет введено, а сразу выделять память тоже думаю не хорошо (mas = (char *)malloc(40)); при этом символов может быть введено больше, чем мы выделили.
9
15 июля 2009 года
Lerkin
3.0K / / 25.03.2003
Цитата: smoki
Я просто пытаюсь разобраться с динамическими массивами, смотрите такая ситуация: нужно подсчитать количество символов введенных с клавиатуры.
В этом случае мы не знаем сколько символов будет введено, а сразу выделять память тоже думаю не хорошо (mas = (char *)malloc(40)); при этом символов может быть введено больше, чем мы выделили.


Ну, для таких целей, правильнее будет выделять память блоками.
А вообще, realloc - медленная дюже. Да и для С++ - это не вариант. Для С - сойдет...

2.1K
15 июля 2009 года
smoki
115 / / 05.11.2006
Цитата: Lerkin
Ну, для таких целей, правильнее будет выделять память блоками.
А вообще, realloc - медленная дюже...



А на код можно посмотреть?

Да и по поводу тех двух примеров. Они имеют право на существование?
Я сомневаюсь по поводу первого

9
15 июля 2009 года
Lerkin
3.0K / / 25.03.2003
Цитата: smoki
А на код можно посмотреть?


Если для С++, то код - проще некуда (ну, пробелы не считает ;)):

 
Код:
...
string buff;
cin >> buff;

cout << "String length: " << buff.size() << endl;

Для С нужен код?
Цитата: smoki

Да и по поводу тех двух примеров. Они имеют право на существование?
Я сомневаюсь по поводу первого


И по поводу второго не сомневайся. Утопить обоих ;)

2.1K
15 июля 2009 года
smoki
115 / / 05.11.2006
Цитата: Lerkin

Для С нужен код?


Да, если можно

Цитата:

И по поводу второго не сомневайся. Утопить обоих ;)


Я подумаю над вашим предложением :D

307
15 июля 2009 года
Artem_3A
863 / / 11.04.2008
твоя "задача", не оч конечно, но работает:

Код:
#include "stdafx.h"
#include <iostream>

using std::cin;
using std::cout;
using std::endl;

int _tmain(int argc, _TCHAR* argv[])
{
    char* str = new char[];
    cin >> str;
    cout << "\nLen enter string: "<<strlen(str)<<endl;
    system("pause");
    return 0;
}


а вообще, если мне не изменяет память, malloc выделяет память, realloc изменяет размер массива, под который уже выделели память. приведенный тобой код мягко говоря не отличается разумом!=) особенно прикольно смотриться бесконечные циклы!=)
2.1K
15 июля 2009 года
smoki
115 / / 05.11.2006
Цитата: Artem_3A
твоя "задача", не оч конечно, но работает:

Код:
#include "stdafx.h"
#include <iostream>

using std::cin;
using std::cout;
using std::endl;

int _tmain(int argc, _TCHAR* argv[])
{
    char* str = new char[];
    cin >> str;
    cout << "\nLen enter string: "<<strlen(str)<<endl;
    system("pause");
    return 0;
}


а вообще, если мне не изменяет память, malloc выделяет память, realloc изменяет размер массива, под который уже выделели память. приведенный тобой код мягко говоря не отличается разумом!=) особенно прикольно смотрится бесконечные циклы!=)



С таким кодом пока сложно, но разгребу потихоньку, а по поводу циклов, они не бесконечные естественно, там приведена часть кода

3
15 июля 2009 года
Green
4.8K / / 20.01.2000
Цитата: Artem_3A

 
Код:
char* str = new char[];
    cin >> str;


Как ты считаешь, память какого размера выделилась?
И сколько туда можно записать?

87
16 июля 2009 года
Kogrom
2.7K / / 02.02.2008
Чтобы учитывать пробелы, приведу пример с функцией, о которой сегодня уже говорил:

Код:
#include <iostream>
#include <string>

using namespace std;

int main()
{
    string str;
    getline(cin, str, '\n');
    cout << str.length();
    return 0;
}

Где-то я уже видел подпись как у автора. Вроде даже на этом форуме...
1
16 июля 2009 года
kot_
7.3K / / 20.01.2000
Цитата: Artem_3A
приведенный тобой код мягко говоря не отличается разумом!=)


это так надо понимать, что приведенный тобой живой и разумный?
Это во первых. Во вторых - этот же код приведен постом выше - разница только в том, что твой привязан к конкретной среде разработки - и помимо ее не скомпилируется.
Топикстартеру стоит более четко формулировать задачу - общим правилом является выделение буфера фиксированного размера, на основании какой либо системной переменной типа MAX_PATH и т.п. перевыделение памяти используется не так часто. Но если используется - то как правило блоками и по алгоритму, позволяющему снизить издержки - так как по сути выполняется три операции
1. Копирование существующей области
2. выделение памяти
3. копирование сохраненой области
- т.е. в любом случае данная операция как минимум не быстрая. У тебя же реаллокация выполняется на каждом шаге - можно затормозить практически любой компьютер. На основании этого сам можешь подумать - годится твой код, и куда.
В С++ более эффективно использовать string для этих задач.

9
16 июля 2009 года
Lerkin
3.0K / / 25.03.2003
Как обещал, код на С (писал не проверяя, поэтому не очень умно и красиво):
Код:
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

// Размер блока памяти
#define MEMBLOCK_SIZE   16


int main( int argc, char* argv[] )
{
    char ch, *buff, *res;
    int _capacity = MEMBLOCK_SIZE, length = 0, tmp_len = 0;

    // Выделим начальный буфер
    buff = (char*)malloc( _capacity );
    memset( buff, '\0', _capacity );

    while (true)
    {
    // Получили символ
    ch = getche();

    // Если Enter, то выйдем
    if (0x0d == ch)
        break;

    if (MEMBLOCK_SIZE == ++tmp_len)
    {
        tmp_len = 0;
        _capacity += MEMBLOCK_SIZE;

        // Выделим новый буфер
        res = (char*)malloc( _capacity );
        memset( res, '\0', _capacity );

        // Перенесем из старого
        memcpy( res, buff, length );
        free( buff );

        // тут понятно :)
        buff = res;
        res = NULL;
    }

    // Собственно, помещаем введенный символ в буфер
    *(buff + length++) = ch;
    }

    printf( "\nВведеная строка:%s\n", buff );
    printf( "Длина введеной строки:%i\n", length );

    free( buff );

    return 0;
}

При этом, никакого удаления символов из строки и прочего редактирования при вводе.
Вот погляди на этот ужоснах, и учи С++.
12K
16 июля 2009 года
lifs
163 / / 06.09.2007
Про код, приведенный Lerkin, вместо:
 
Код:
// Выделим новый буфер
        res = (char*)malloc( _capacity );
        memset( res, '\0', _capacity );

        // Перенесем из старого
        memcpy( res, buff, length );
        free( buff );

лучше либо делать realloc(...), потому что гипотетически он может использовать память следом за буфером без лишнего копирования, либо делать связанным списоком.
9
16 июля 2009 года
Lerkin
3.0K / / 25.03.2003
Код, приведенный Lerkin, лучше вообще не использовать. Ибо: что realloc, что связный список - ни производительности, ни удобства использования в С не добавляют.
29K
17 июля 2009 года
Ander Skirnir
109 / / 08.06.2009
Да вроде бы связный список - хорошая штука. Могу предложить сделать связный список кусков строк. Что-то такое:

Код:
#include <stdio.h>

#define SLEN 10

typedef unsigned char byte;
typedef struct strlist string;

struct strlist
{
    char cbuff[SLEN];
    string *next;
};

string readline (void)
{
    string result, *iter = &result;

    byte i = 0;
    while ((iter->cbuff[i++] = getchar()) != '\n')
        if (i == SLEN - 1)
            i = 0, iter->next = iter = (string*)malloc(sizeof(string));

    iter->cbuff[--i] = '\0';

    return result;
}

int strlength (string str)
{
    byte i = 0, n = 0;
    while (str.cbuff[n++,i++] != '\0')
        if (i == SLEN - 1)
            i = 0, str = *str.next;

    return n - 1;
}

void strfree (string str)
{
    string *iter = str.next, *inext = (iter) ? iter->next : NULL;

    while (iter)
    {
        free(iter);
        iter = inext;
        inext = (inext) ? inext->next : NULL;
    }
}

int main ()
{
    string str = readline();
    printf("length = %d\n", strlength(str));
    strfree(str);
}
12K
17 июля 2009 года
lifs
163 / / 06.09.2007
Цитата: Lerkin
Код, приведенный Lerkin, лучше вообще не использовать. Ибо: что realloc, что связный список - ни производительности, ни удобства использования в С не добавляют.



Так как же еще организовать ввод данных в C неизвестной (произвольной) длины? Вполне рабочий пример, если его немного переделать (изменить размер начального сегмента, попытавшись оценить примерный размер данных, изменить алгоритм увеличения буфера), то все будет совсем неплохо.

Ксати, кроме динамического буфера и связанного списка, можно еще писать в файл, только скорость от этого не прибавится :D

288
17 июля 2009 года
nikitozz
1.2K / / 09.03.2007
Цитата: lifs
Так как же еще организовать ввод данных в C неизвестной (произвольной) длины? Вполне рабочий пример, если его немного переделать (изменить размер начального сегмента, попытавшись оценить примерный размер данных, изменить алгоритм увеличения буфера), то все будет совсем неплохо.

Ксати, кроме динамического буфера и связанного списка, можно еще писать в файл, только скорость от этого не прибавится :D



Это смотря каких данных и что с ними потом нужно будет делать. :)
Основная проблема с realloc в том, что при выделении нового буфера придется копировать старые данные в новый буфер. Этого можно избежать, если размещать данные "постранично" (по-моему это предлагал Ander Skirnir).

3
17 июля 2009 года
Green
4.8K / / 20.01.2000
Ну вы прям раздули проблему из ничего.
Посмотри, как устроен std::string и все станет ясно.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог