Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Разное

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: C++ копирование строк или strcpy...
 
 автор: Евгений Петров   (04.05.2006 в 18:23)   письмо автору
 
 

И снова я с этими строками на С++ :)
Почему глючит следующий код?
#include <string.h>

void main()
{
    char * str1 = "str1";
    char * str2 = "str2";
    strcpy(str1,str2);
}

   
 
 автор: Trianon   (04.05.2006 в 18:26)   письмо автору
 
   для: Евгений Петров   (04.05.2006 в 18:23)
 

Вы пытаетесь записать одну константу поверх другой.
Переменные у Вас не строковые. Переменные - лишь указатели на символ ( символьный массив) . Но сам массив - константный.

   
 
 автор: Евгений Петров   (04.05.2006 в 18:39)   письмо автору
 
   для: Trianon   (04.05.2006 в 18:26)
 

И как мне скопировать содержимое str2 в str1?

   
 
 автор: Trianon   (04.05.2006 в 19:07)   письмо автору
 
   для: Евгений Петров   (04.05.2006 в 18:39)
 

Сперва распределить где-то память под строку, потом уже в нее копировать.

#include <string.h> 

void main() 

    char * str1 = "str1"; 
    char * str2 = "str2"; 
    str1 = malloc(strlen(str2)+1);
    strcpy(str1,str2); 
}

   
 
 автор: Евгений Петров   (04.05.2006 в 19:38)   письмо автору
 
   для: Trianon   (04.05.2006 в 19:07)
 

А если мне надо, чтобы память не выделялась по новой а записывалась туда где есть, я обьяснб на конкретном примере:
Есть класс:
class CTest
{
private:
    char * str;
public:
    CTest();    
    ~CTest();
    void Init(char *);
};

В конструкторе выделяем память для str
CTest::CTest()
{
    str = new char[6];
}

в деструкторе освобождаем её:
CTest::~CTest()
{
    delete str;
}

А в методе Init надо записать в str новое значение:
void CTest::Init(char * nStr)
{
    str = nStr;
}

Проблема в том, что если сделать так как я это написал, то в строке
str = nStr;

Создастся новая строка у которой будет другой адрес и при вызове деструктора компилятор не сможет освободить память которая была выделена в конструкторе:
void main()
{
    char * str = "String";
    CTest * Test1 = new CTest();    
    Test1->Init(str);   
    delete Test1; // Заглючит
}

   
 
 автор: Trianon   (04.05.2006 в 19:49)   письмо автору
 
   для: Евгений Петров   (04.05.2006 в 19:38)
 

Тогда и копировать надо туда, где эта память распределена. Только туда больше 6 байт (в Вашем примере ) не положишь.
void CTest::Init(char * nStr) 

    strncpy(str, nStr, 6); 


Или распределять память непосредственно перед копированием (возможно, освободив перед этим предыдущий резерв)

   
 
 автор: Евгений Петров   (04.05.2006 в 20:18)   письмо автору
 
   для: Trianon   (04.05.2006 в 19:49)
 

О, это похоже то что надо, хотя может и нет...
Вообщем усложним немного задачу и будем использовать не одну строку а массив таких строк, т.е.:
char ** str = new char*[10]

т.е. 10 строк... (эта цифра задается динамически)
Так вот в методе Init нужно забить этот массив значениями так чтобы потом в деструкторе он нормально удалился... Все строки произвольной и разной длинны... Как посоветуете это осуществить?

   
 
 автор: Trianon   (04.05.2006 в 20:26)   письмо автору
 
   для: Евгений Петров   (04.05.2006 в 20:18)
 

Я, честно говоря, не понял в чем трудность. В методе init и в деструкторе цикл не написать?

   
 
 автор: Евгений Петров   (04.05.2006 в 20:43)   письмо автору
 
   для: Trianon   (04.05.2006 в 20:26)
 

Тьфу! :)) Я только что понял что я сказал :)) Спасибо Вам огромное!!! Что самое интересное,что раньше пробовал тоже самое и не получалось :))

   
 
 автор: Евгений Петров   (04.05.2006 в 21:24)   письмо автору
 
   для: Евгений Петров   (04.05.2006 в 20:43)
 

А вот ещё вопросик маленький.Допустим у меня есть метод:
char * Method( void );

Он должен вернуть указатель на строку, строку эту я динамически создаю в этом методе:
char * CMyClass::Method( void )
{
  char * str = new char[10];
  ...
  return str;
}

Как и где нужно освобождать память для str?

   
 
 автор: Евгений Петров   (04.05.2006 в 19:41)   письмо автору
 
   для: Trianon   (04.05.2006 в 19:07)
 

Да, кстати, я на С++ пишу... malloc - это если мне память не изменяет в С аналог new, поэтому писать надо тогда:
#include <string.h> 

void main() 

    char * str1 = "str1"; 
    char * str2 = "str2"; 
    str1 = new char[strlen(str2)+1]; 
    strcpy(str1,str2); 
}

   
 
 автор: cheops   (04.05.2006 в 21:34)   письмо автору
 
   для: Евгений Петров   (04.05.2006 в 19:41)
 

Да в C++ лучше использовать new.

   
 
 автор: Евгений Петров   (04.05.2006 в 23:06)   письмо автору
 
   для: cheops   (04.05.2006 в 21:34)
 

Хм а разве в С++ вообще есть функция malloc? Я думал это функция С (без ++ :) )
И где все таки удалять выделенную память? :)
Да и ещё вопрос на засыпку. :) Как преобрзовать char * в CString?

   
 
 автор: Евгений Петров   (04.05.2006 в 23:24)   письмо автору
 
   для: Евгений Петров   (04.05.2006 в 23:06)
 

Про преобразование нашел сам:
(char*)(LPCTSTR)str;

Поэтому заменяю эот вопрос следующим: :))
char ** str_array = new char*[10];

Как теперь можно узнать размер этого массива?
sizeof(str_array) возвращает 4 - т.е. насколько я понимаю размер указателя на начало массива...

   
 
 автор: cheops   (05.05.2006 в 08:33)   письмо автору
 
   для: Евгений Петров   (04.05.2006 в 23:06)
 

C++ это расширение C - поэтому все библиотеки С в C++ имеются. Вообще C++ основан на стандарте С89, однако уже появился стандарт C99, который тем не менее мало кем поддерживается.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования