Вопрос по C++

Для тех, кто хочет сделать мир лучше.
Сообщение
Автор
Fire666
Эксперты no-Steam
Эксперты no-Steam
Сообщения: 2600
Зарегистрирован: 15.02.2007
Откуда: Москва
Благодарил (а): 2 раза
Поблагодарили: 43 раза
Контактная информация:

#61 Сообщение 19.09.2010, 18:15

Зачем ?

Код: Выделить всё

   char *res=new char[140]; // a 140-byte array
   memset(res,0,140);
   res[0]=0;
   return res;
Если лучше

Код: Выделить всё

   char res[140];
   memset(res,0, sizeof(res) );

   return res;
Нафиг после мемсета делать еще и res[0]=0
Последний раз редактировалось $t@t!c_V()1D 19.09.2010, 18:15, всего редактировалось 2 раза.
Причина: Ну, мог и так, но предпочёл оптимизации вариант "почувствуй разницу"

Аватара пользователя
GanGSISoft
Полковник
Полковник
Сообщения: 1430
Зарегистрирован: 27.03.2008
Откуда: Бацькаўшчына
Благодарил (а): 2 раза
Поблагодарили: 3 раза
Контактная информация:

#62 Сообщение 19.09.2010, 19:01

И зачем "bla"? оно у меня на нём тогда вылетает, и пишет что неверный указатель 0xcccccccc. Тут не в функции проблема, в в том что объявление вида char *s=new char; char *s=new char[100] в любой функции приводят к ошибке, но в других программах эти функции работают нормально.
Короче буду искать проблему сам коментированием, думал что в чём то конкретно ошибся и ткнёте носом.

И как создать бесконечную строку, как в delphi string?

Аватара пользователя
NiGHt-LEshiY
Полковник
Полковник
Сообщения: 10258
Зарегистрирован: 13.06.2008
Откуда: Россия
Благодарил (а): 752 раза
Поблагодарили: 2667 раз
Контактная информация:

#63 Сообщение 19.09.2010, 19:03

GanGSISoft
Перестань сравнивать языки уже.
Скажи, что должна делать строка?
Кодекс поведения участников сообщества — обязательно к прочтению.
Просьба присылать сообщения об ошибках в ЛС.

Аватара пользователя
GanGSISoft
Полковник
Полковник
Сообщения: 1430
Зарегистрирован: 27.03.2008
Откуда: Бацькаўшчына
Благодарил (а): 2 раза
Поблагодарили: 3 раза
Контактная информация:

#64 Сообщение 19.09.2010, 19:11

NiGHt-LEshiY
это строка была бесконечна, почти, очень длинная короче, можно было текстовый файл 1мб в неё целиком загрузить.

Аватара пользователя
NiGHt-LEshiY
Полковник
Полковник
Сообщения: 10258
Зарегистрирован: 13.06.2008
Откуда: Россия
Благодарил (а): 752 раза
Поблагодарили: 2667 раз
Контактная информация:

#65 Сообщение 19.09.2010, 19:13

Соу?
char veryverylongstring[1024*1024*1024];
1024*1024*1024 только для удобства, чтобы было понятней.
Кодекс поведения участников сообщества — обязательно к прочтению.
Просьба присылать сообщения об ошибках в ЛС.

Аватара пользователя
GanGSISoft
Полковник
Полковник
Сообщения: 1430
Зарегистрирован: 27.03.2008
Откуда: Бацькаўшчына
Благодарил (а): 2 раза
Поблагодарили: 3 раза
Контактная информация:

#66 Сообщение 19.09.2010, 19:17

NiGHt-LEshiY
ага, но оно наверное сразу займёт всё память размером 1024*1024*1024?
Там просто можно было свободно объявлять кучу строк типа string и не беспокоится о их длине и прочем. Или и тут так?

Fire666
Эксперты no-Steam
Эксперты no-Steam
Сообщения: 2600
Зарегистрирован: 15.02.2007
Откуда: Москва
Благодарил (а): 2 раза
Поблагодарили: 43 раза
Контактная информация:

#67 Сообщение 19.09.2010, 19:21

GanGSISoft, тут все дело зависит от того сколько памяти ты выделишь под буфер.

В этом смысле легче всего работать с файлами, так как там размер буфера просто делается равным размеру файла.

Выделить память можно несколькими методами.

char test[512];
char *test = ( char * )malloc( 512 );
char *test = new char[ 512 ];

оптимальным вариантом считаю первый.

А вообще используй если уж на то пошло не char, а Cstring.

Аватара пользователя
NiGHt-LEshiY
Полковник
Полковник
Сообщения: 10258
Зарегистрирован: 13.06.2008
Откуда: Россия
Благодарил (а): 752 раза
Поблагодарили: 2667 раз
Контактная информация:

#68 Сообщение 19.09.2010, 19:27

Да, займет. Хочешь динамически выделять - добро пожаловать:

Код: Выделить всё

int size = 256; // начальный размер строки
char *veryverylongstring = new char[size];
// тут проверка на длину входящего сообщения/файла/чего-то ещё
while (size < strLength) // если размер меньше длины, 
{
  delete [] string;
  size *= 2;
  char *string = new char[size]; // увеличили длину вдвое и инициализировали заново
  // тут считываем данные ещё раз, если опять длина меньше - цикл повторится
}
// делаем что-то со строкой
delete [] string;
Добавлено спустя 23 секунды:
Fire666
Первый - статическое выделение. Вся ответственность на компиляторе...
Кодекс поведения участников сообщества — обязательно к прочтению.
Просьба присылать сообщения об ошибках в ЛС.

Аватара пользователя
GanGSISoft
Полковник
Полковник
Сообщения: 1430
Зарегистрирован: 27.03.2008
Откуда: Бацькаўшчына
Благодарил (а): 2 раза
Поблагодарили: 3 раза
Контактная информация:

#69 Сообщение 19.09.2010, 19:29

Спасибо.
И что такое Cstring и какие плюcы и минусы перед char* и соместимо ли оно с char*

Fire666
Эксперты no-Steam
Эксперты no-Steam
Сообщения: 2600
Зарегистрирован: 15.02.2007
Откуда: Москва
Благодарил (а): 2 раза
Поблагодарили: 43 раза
Контактная информация:

#70 Сообщение 19.09.2010, 19:32

NiGHt-LEshiY, ну пускай и статическое выделение, я просто не понимаю, что GanGSISoft, так переживает из-за памяти.

GanGSISoft, какая тебе разница. будет ли равен объем выделенной памяти размеру рабочего материала ( текст и т.д. ) или же объем будет больше.

Имхо главное, что бы он был не меньше.

Я понимаю, если бы ты писал под MS Dos с ограниченными возможностями использования памяти.

Аватара пользователя
NiGHt-LEshiY
Полковник
Полковник
Сообщения: 10258
Зарегистрирован: 13.06.2008
Откуда: Россия
Благодарил (а): 752 раза
Поблагодарили: 2667 раз
Контактная информация:

#71 Сообщение 19.09.2010, 20:04

Fire666
Предположим, что в программу будут вводиться данные от 1 байта до 2 с чем-то гигов (ограничение 32 бит).
Если юзеру нужно 10 байт, а статически будут выделяться все 2 гига? Получится расчудесно.
Кодекс поведения участников сообщества — обязательно к прочтению.
Просьба присылать сообщения об ошибках в ЛС.

Fire666
Эксперты no-Steam
Эксперты no-Steam
Сообщения: 2600
Зарегистрирован: 15.02.2007
Откуда: Москва
Благодарил (а): 2 раза
Поблагодарили: 43 раза
Контактная информация:

#72 Сообщение 19.09.2010, 20:09

NiGHt-LEshiY писал(а):Fire666
Предположим, что в программу будут вводиться данные от 1 байта до 2 с чем-то гигов (ограничение 32 бит).
Если юзеру нужно 10 байт, а статически будут выделяться все 2 гига? Получится расчудесно.
Мда :)

Аватара пользователя
x_000
Полковник
Полковник
Сообщения: 4889
Зарегистрирован: 25.02.2008
Откуда: Deutsches Reich
Благодарил (а): 6 раз
Поблагодарили: 18 раз

#73 Сообщение 19.09.2010, 22:01

Код: Выделить всё

char *pointer;

__asm {
   sub esp, size
   mov pointer, esp
}
вот он, лучший способ же
Последний раз редактировалось $t@t!c_V()1D 19.09.2010, 22:01, всего редактировалось 2 раза.
Причина: у Икси "метал"...как всегда %)

Lev2008
Лейтенант
Лейтенант
Сообщения: 221
Зарегистрирован: 08.11.2008

#74 Сообщение 20.09.2010, 11:52

$t@t!c_V()1D

Код: Выделить всё

char *s = new char[200];
s[0]=0;
strcat(s, "Hello world");
Открываем MSDN и читаем про функцию strcat:
Parameters
strDestination
Null-terminated destination string.
strSource
Null-terminated source string.
Т.е. на входе она принимает заканчивающиеся нулем строки. Условие выполнено? Да.
Remarks
The strcat function appends strSource to strDestination and terminates the resulting string with a null character. The initial character of strSource overwrites the terminating null character of strDestination.
Перевод:
Функция strcat добавляет strSource к strDestination и завершает результирующую строку нулевым символом. Первый символ strSource перезаписывает собой завершающий нуль-символ strDestination.
Т.е. в итоге выполнения приведенного выше куска кода мы получим в s поинтер на выделенный блок памяти, который будет содержать следующие символы:
"Hello world\0", за которыми будет следовать мусор. Если мы потом сделаем, например:

Код: Выделить всё

printf("%s", s);
Получим в консоли "Hello world". Вывод? В данном случае, нет смысла занулять весь буфер.

GanGSISoft
Ошибок в коде очень много. Тебе надо неспеша осваивать, раз уж хочется именно С++. Парсить XML... Начни с более малого. Не думаю что имеет смысл открывать здесь клуб "изучи С++ за 2 дня". Купи какую-нибудь книжку.
Но всё же:
1. Выделение памяти.

Код: Выделить всё

char *s; // Объявление указателя. Самого по себе его нельзя использовать, он не имеет под собой реального пространства для хранения данных.
s = new char[200] // Выделение реального блока памяти для хранения данных. Адрес блока сохраняется в s. Размер char равен 1 байту, поэтому указывается что нужен блок не в один символ, а массив.
s[0] = 0; // Функции по работе со строками требуют заканчивающиеся нулем строки.
delete [] s; // Освобождение блока памяти. Иначе он так и останется висеть. Используются [] чтобы delete знала, что освобождается массив.
Всё это есть в простейших учебниках по C++.
2. Соблюдение порядка

Код: Выделить всё

   if(ans=='y'){
   fopen_s(&fp,fn,"r");
   //...
   }
   fclose(fp);
Где открываешь файл там и закрывай:

Код: Выделить всё

   if(ans=='y'){
   fopen_s(&fp,fn,"r");
   //...
   fclose(fp);
   }
3. Выход за границы блока

Код: Выделить всё

      while(bc!='\n'){
         bc=fgetc(fp);
         buf[i]=bc;
         i++;
      }
Здесь надо проверять, что i меньше размера блока buf. Потому что иначе ты рискуешь начать портить данные в памяти.

И т.д. и т.п.

Аватара пользователя
NiGHt-LEshiY
Полковник
Полковник
Сообщения: 10258
Зарегистрирован: 13.06.2008
Откуда: Россия
Благодарил (а): 752 раза
Поблагодарили: 2667 раз
Контактная информация:

#75 Сообщение 20.09.2010, 13:28

В данном случае, нет смысла занулять весь буфер.
Лучше сразу привыкать к правильному программированию, чем постоянно создавать себе мнимые исключения из правил.
Кодекс поведения участников сообщества — обязательно к прочтению.
Просьба присылать сообщения об ошибках в ЛС.

Ответить