C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Правильное выделение памяти
Андрей
Отправлено: 23.09.2004, 10:17


Не зарегистрирован







У меня задача из DLL передать в программу данные ввиде строки. Размер данных может быть 5, а может быть и 10000 символов, а то и больше.

Написал пример для проверки.
Так вот, такая конструкция не работает (т.е. она работает, но вставляет символя псевдографики в любые места). Вроде правильно написал.

char word [100] = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";

char *ptr;

if ((ptr = (char *) malloc(10000)) == NULL)
{
printf ("Не хватает памяти !");
return "";
}

for (int i = 1; i <= 1000; i++)
strcat (ptr, word);

printf ("%s", ptr);

free(ptr);
Андрей
Отправлено: 23.09.2004, 10:40


Не зарегистрирован







Все настолько плохо ? sad.gif
Konstantine
Отправлено: 23.09.2004, 10:41


Мастер участка

Группа: Модератор
Сообщений: 545



1) Попробуй через new-delete
2) выделяешь ТЫ 10_000 байт, а впихиваешь 100_000!!!
Андрей
  Отправлено: 23.09.2004, 10:46


Не зарегистрирован







Для Konstantin:

1. Все тоже самое, только теперь при выполнении примера комп пищит.
2. Ошибся
Shura
Отправлено: 23.09.2004, 10:56


Дежурный стрелочник

Группа: Участник
Сообщений: 45



char word [100] = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"

в этой строке 100 символов. А куда будет умещаться символ конца строки ('\n')?

2. Как сказал Konstantineне не пользуй malloc, пользуй new.
3. malloc(10000) — попробуй выделить чуть больше.

4.
for (int i = 1; i <= 1000; i++)
strcat (ptr, word);

Стремная конструкция! Попробуй сначала обнулить содержимое ptr.

Отредактировано Shura — 23/09/2004, 11:59
Konstantine
Отправлено: 23.09.2004, 11:12


Мастер участка

Группа: Модератор
Сообщений: 545



а комп пищит где? в какой строке ему не нравится?

попробуй вместо strcat использовать CopyMemory или побайтно копь

P.S.: ( to [Андрей] & [Shura] ) ник у меня, всё-таки "Konstantine" !!!
Андрей
  Отправлено: 23.09.2004, 13:39


Не зарегистрирован







Для Konstantine: Извини если обидел на счет ника

Комп пищит похоже из-за появления в следствии копирования в строке непонятных символов псевдографики ...

а если по байтно копировать, то все ОК ... странно все это ...
Konstantine
Отправлено: 23.09.2004, 14:21


Мастер участка

Группа: Модератор
Сообщений: 545



ИМХО сдаётся что STRCAT криво в винде работает.... а CopyMemory пробовал? лучше им!

копирования??? или отображения? т.к. есть символ (вроде 0Bh) что сигал подаёт.... и printf его обрабатует...

кстати... какой printf в dll?!?!?!?!

Отредактировано Konstantine — 23/09/2004, 15:25
Андрей
Отправлено: 23.09.2004, 14:45


Не зарегистрирован







Для Konstantine:

printf в dll естественно нет ... я сделал тестовую программку ...

а каков вызов CopyMemory ? я что то не нашел в справке формат вызова.
xim
Отправлено: 23.09.2004, 15:41


Станционный диспетчер

Группа: Участник
Сообщений: 143



[CODE]char word [100] = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";

Как я понимаю, строка из 100 символов не может поместиться в
char word[100] (некуда поместить '<!--POST BOX-->'). Поэтому strcat дает в итоге
стоки с символом '\x07' — так что писк может возникнуть. А так, многие предыдущие советы были правильными. Пиши ~:

#define NUMBER_OF_STRINGS 1000
...
int szPtr=NUMBER_OF_STRINGS*strlen(word)+1;
char *ptr=new char[szPtr];
ZeroMemory(ptr,szPtr);

for(int index=0;index lstrcat(ptr,word);
xim
Отправлено: 23.09.2004, 15:42


Станционный диспетчер

Группа: Участник
Сообщений: 143



char word [100] = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";

Как я понимаю, строка из 100 символов не может поместиться в
char word[100] (некуда поместить '<!--POST BOX-->'). Поэтому strcat дает в итоге
стоки с символом '\x07' — так что писк может возникнуть. А так, многие предыдущие советы были правильными.

Пиши ~:

#define NUMBER_OF_STRINGS 1000
...
int szPtr=NUMBER_OF_STRINGS*strlen(word)+1;
char *ptr=new char[szPtr];
ZeroMemory(ptr,szPtr);

for(int index=0;index lstrcat(ptr,word);
xim
Отправлено: 23.09.2004, 15:44


Станционный диспетчер

Группа: Участник
Сообщений: 143



Блин, вот этот <!--POST BOX--> ето символ нуль
xim
Отправлено: 23.09.2004, 15:51


Станционный диспетчер

Группа: Участник
Сообщений: 143



Последняя строчка:

CODE

for(int index=0;index<NUMBER_OF_STRINGS;index++)
lstrcat(ptr,word);

HTML
Блин, из-за этого парсера код набрать невозможно wink.gif
Shura
Отправлено: 23.09.2004, 16:11


Дежурный стрелочник

Группа: Участник
Сообщений: 45



Konstantine, извини, там просто пробел выпал :-)

Сейчас подумал, что возможен такой вариант — символ конца строки не влазит в массив и его там нет, в связи с этим strcat() не может определить где строка кончается чтобы добавить новую и в итоге просто выходит за границу массива.
Konstantine
Отправлено: 23.09.2004, 16:22


Мастер участка

Группа: Модератор
Сообщений: 545



QUOTE (Shura @ 23/09/2004, 17:13)
strcat() не может определить где строка кончается чтобы добавить новую и в итоге просто выходит за границу массива.

в таком случае должно работать
CODE
char *word = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
в чём Я конечно сомневаюсь...
всё-таки я предлагаю, что в этой ситуации (зная размеры строк) воспользоваться CopyMemory!

Отредактировано Konstantine — 23/09/2004, 17:24
timson
Отправлено: 28.09.2004, 06:19


Станционный диспетчер

Группа: Участник
Сообщений: 82



ясен пень, что '<!--POST BOX-->' не лезет..

возможно повторюсь (скорее всего):
CODE

char str[] = "string";

char* pStr = (char*) malloc( strlen(str) * N + 1 );
pStr[0] = '<!--POST BOX-->';

for (int i = 0; i < N; ++i)
{
strcat(pStr, str);
}


а если CopyMemory, то надо следить за символом '<!--POST BOX-->'....
olegenty
Отправлено: 28.09.2004, 07:05


Ветеран

Группа: Модератор
Сообщений: 2412



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

да, вспоминая самое начало работы в Builder, когда я пересел на него с Borlad C++ 3.1, почему-то всё, связанное с char* глючило по недетски, и кусок кода, работавший в C++ 3.1 не работал в Builder.
Konstantine
Отправлено: 28.09.2004, 08:41


Мастер участка

Группа: Модератор
Сообщений: 545



Просто в билдере вункции библиотеки string.h неверно работают. нада CopyMemory. причём, Андрей, не нашёл — нада искать по F1 — откроется встроеный MS SDK хелп ,и там расписано что куда, а то как ты искал (я так понял по CTRL+SHIFT+SPACE) — так токо функции работают, а это — макрос.
Boyko
Отправлено: 28.09.2004, 10:32


Станционный диспетчер

Группа: Участник
Сообщений: 88



QUOTE (Konstantine @ 28/09/2004, 08:43)
Просто в билдере вункции библиотеки string.h неверно работают. нада CopyMemory. причём, Андрей, не нашёл

1) У меня strcat() работает правильно ( C++ Builder 6.0)
2) Если CopyMemory() не нашел, есть тоже memcpy()...
timson
Отправлено: 28.09.2004, 19:36


Станционный диспетчер

Группа: Участник
Сообщений: 82



толкну свое слово:


как обычно стали забывать о временах не ООП и стандартных функций.
зачем AnsiString — это же ООП, раздут код, памяти сожрет, да и работать медленней будет, да и кусок кода на другую платформу (VC) не перенесешь.

пользуйтесь стандартными, вечными и везде (ОС, платформы) поддерживаемыми функциями, стандарт есть стандарт..

и если что-то работало, а потом не работало (со стандартыми вещами), то скорее всего lefthands помогли.

внутри CopyMemory скорее всего лежит memcpy, а в ZeroMemory — будет memset(dst, 0, size_dst);
это всего лишь надстройки (сюда и AnsiString и VCL), надо всем стандартным, облегчающее жизнь, но несущще ссобою всю кривость, и не гибкость..

я сам пользуюсь vcl'ом, но в меру. ключевое слово здесь (vcl) Visual...
olegenty
Отправлено: 29.09.2004, 08:19


Ветеран

Группа: Модератор
Сообщений: 2412



как раз прихожу к тому же, знакомлюсь с STL и хочу все самописные классы, построенные на наследниках TList переписать на vector

Вернуться в Вопросы программирования в C++Builder