Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.08.2012, 16:54   #1
lanakramoleb
Новичок
Джуниор
 
Регистрация: 17.08.2012
Сообщений: 5
По умолчанию проблема при выделении памяти.

Всё нормально компилируется и запускается, но после выполнения этой функции:

Код:
void disp() {
	char *str;
	str = new char[14];
	for(int i=0;i<SIZE;i++)	 {
		if(*Squad[i].name) {
			cout << '\n' << Squad[i].name << '\n';
			str = (Squad[i].alive)? (char *)"Alive " : (char *)"!Dead! ";
			cout << str;
			str = (Squad[i].health)? (char *)"Healthy " : (char *)"!Injured! ";
			cout << str;
			str = (Squad[i].ready)? (char *)"Ready " : (char *)"!Training! ";
			cout << str;
			str = (Squad[i].armed)? (char *)"Armed " : (char *)"!Empty! ";
			cout << str;
			str = (Squad[i].morale)? (char *)"High morale\n" : (char *)"!Low morale!\n";
			cout << str;
		}
	}
	delete [] str;
}
в терминале получаем вот это:

Код:
John
Alive Healthy Ready Armed High morale
*** glibc detected *** ./bits: free(): invalid pointer: 0x08049256 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x73e42)[0x452e42]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0x1b951f]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdaPv+0x1b)[0x1b957b]
./bits[0x8048e27]
./bits[0x8048889]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x3f84d3]
./bits[0x8048781]
======= Memory map: ========
00110000-001e8000 r-xp 00000000 08:01 1316339    /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
001e8000-001e9000 ---p 000d8000 08:01 1316339    /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
001e9000-001ed000 r--p 000d8000 08:01 1316339    /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
001ed000-001ee000 rw-p 000dc000 08:01 1316339    /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
001ee000-001f5000 rw-p 00000000 00:00 0 
001f5000-0021f000 r-xp 00000000 08:01 131774     /lib/i386-linux-gnu/libm-2.15.so
0021f000-00220000 r--p 00029000 08:01 131774     /lib/i386-linux-gnu/libm-2.15.so
00220000-00221000 rw-p 0002a000 08:01 131774     /lib/i386-linux-gnu/libm-2.15.so
00325000-00326000 r-xp 00000000 00:00 0          [vdso]
003bd000-003dd000 r-xp 00000000 08:01 131722     /lib/i386-linux-gnu/ld-2.15.so
003dd000-003de000 r--p 0001f000 08:01 131722     /lib/i386-linux-gnu/ld-2.15.so
003de000-003df000 rw-p 00020000 08:01 131722     /lib/i386-linux-gnu/ld-2.15.so
003df000-0057e000 r-xp 00000000 08:01 131742     /lib/i386-linux-gnu/libc-2.15.so
0057e000-00580000 r--p 0019f000 08:01 131742     /lib/i386-linux-gnu/libc-2.15.so
00580000-00581000 rw-p 001a1000 08:01 131742     /lib/i386-linux-gnu/libc-2.15.so
00581000-00584000 rw-p 00000000 00:00 0 
0079f000-007bb000 r-xp 00000000 08:01 131763     /lib/i386-linux-gnu/libgcc_s.so.1
007bb000-007bc000 r--p 0001b000 08:01 131763     /lib/i386-linux-gnu/libgcc_s.so.1
007bc000-007bd000 rw-p 0001c000 08:01 131763     /lib/i386-linux-gnu/libgcc_s.so.1
08048000-0804a000 r-xp 00000000 08:01 1180574    /home/lanakramoleb/Workspace/bits/Debug/bits
0804a000-0804b000 r--p 00001000 08:01 1180574    /home/lanakramoleb/Workspace/bits/Debug/bits
0804b000-0804c000 rw-p 00002000 08:01 1180574    /home/lanakramoleb/Workspace/bits/Debug/bits
097a2000-097c3000 rw-p 00000000 00:00 0          [heap]
b776c000-b7770000 rw-p 00000000 00:00 0 
b7785000-b7789000 rw-p 00000000 00:00 0 
bffd4000-bfff5000 rw-p 00000000 00:00 0          [stack]
Aborted
Чувствую, что код вышел чем-то корявый. Вот есть желание разобраться.
lanakramoleb вне форума Ответить с цитированием
Старый 17.08.2012, 17:06   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

Вместо str = надо пользоваться strcpy(str,...)
Кроме того, непонятно с какой целью это делается - str потом нигде не используется.
waleri вне форума Ответить с цитированием
Старый 17.08.2012, 17:12   #3
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Неясно зачем здесь вообще переменная str. В крайнем случае, можно обойтись без выделения памяти
Код:
void disp ()
{
  const char *str = NULL;
  for(int i=0;i<SIZE;i++) {
    if(*Squad[i].name) { // перед разыменованием лучше проверить указатель на 0
//  if (Squad[i].name != NULL && *Squad[i].name) {
      cout << '\n' << Squad[i].name << '\n';
      str = (Squad[i].alive)? "Alive " : "!Dead! ";
      cout << str;
      str = (Squad[i].health)? "Healthy " : "!Injured! ";
      cout << str;
      str = (Squad[i].ready)? "Ready " : "!Training! ";
      cout << str;
      str = (Squad[i].armed)? "Armed " : "!Empty! ";
      cout << str;
      str = (Squad[i].morale)? "High morale\n" : "!Low morale!\n";
      cout << str;
  }
}
netrino вне форума Ответить с цитированием
Старый 17.08.2012, 17:38   #4
lanakramoleb
Новичок
Джуниор
 
Регистрация: 17.08.2012
Сообщений: 5
По умолчанию

Без str - это используя конструкцию

Код:
if(Squad[i].alive) 
     cout << "Alive ";
else
     cout << "!Dead! ";
???

Ибо
Код:
cout << (Squad[i].alive)? "Alive " : "!Dead! ";
работать не будет.
lanakramoleb вне форума Ответить с цитированием
Старый 17.08.2012, 17:46   #5
lanakramoleb
Новичок
Джуниор
 
Регистрация: 17.08.2012
Сообщений: 5
По умолчанию

И всё же, что там было не так? Выделение памяти я использовал чтобы разобраться конкретней с ним.
lanakramoleb вне форума Ответить с цитированием
Старый 17.08.2012, 17:59   #6
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Цитата:
Сообщение от lanakramoleb Посмотреть сообщение
Без str - это используя конструкцию

Код:
if(Squad[i].alive) 
     cout << "Alive ";
else
     cout << "!Dead! ";
???

Ибо
Код:
cout << (Squad[i].alive)? "Alive " : "!Dead! ";
работать не будет.
А вот так будет
Код:
cout << (Squad[i].alive? "Alive" : "!Dead!");
"" - строковый литерал, текст, в него заключённый, размещается в секции данных программы. Когда Вы пишете
Код:
const char *str = "Hello, world!";
str - указатель. В данном случае он указывает на данные (текст) в секции данных программы. Освободить (delete, free) статические данные нельзя, о чём Вам и сообщается в ошибке.
str содержит лишь адрес, но не сами данные, потому когда Вы последовательно меняете значение str, меняется лишь адрес, в него помещённый, но данные не копируются.
Код:
char *str = new char [10]; // str указывает на выделенную память
str = (char *)"hello"; // str указывает на hello. при этом адрес выделенной памяти утерян.
Как сказали выше, для копирования данных нужно использовать strcpy (если это строка)

Код:
char *str = new char [10]; // str указывает на выделенную память
strcpy (str, "Hello"); // в выделенную память копируется текст Hello
delete[] str; // освобождается выделенная память
netrino вне форума Ответить с цитированием
Старый 17.08.2012, 18:00   #7
Last
В прострации
Форумчанин
 
Регистрация: 13.01.2009
Сообщений: 239
По умолчанию

Код:
cout << str;
Этот код выводит содержимое памяти, пока не встретит символ '\0'. А где он его встретит? А хрен его знает.

netrino расписал всё очень подробно, читайте его пост =)

[offtop]Чтобы разобраться с выделением памяти нужно писать что-нибудь более компактное, ИМХО.[/offtop]
Пол-жизни сидючи, в монитор глядючи...

Последний раз редактировалось Last; 17.08.2012 в 18:03.
Last вне форума Ответить с цитированием
Старый 17.08.2012, 18:03   #8
lanakramoleb
Новичок
Джуниор
 
Регистрация: 17.08.2012
Сообщений: 5
По умолчанию

Спасибо.

Цитата:
Освободить (delete, free) статические данные нельзя, о чём Вам и сообщается в ошибке.
Не подумал об этом. А что есть указатель я всё же в курсе.

А со скобками вообще стыдно (((
lanakramoleb вне форума Ответить с цитированием
Старый 17.08.2012, 18:17   #9
lanakramoleb
Новичок
Джуниор
 
Регистрация: 17.08.2012
Сообщений: 5
По умолчанию

Цитата:
Сообщение от Last Посмотреть сообщение
[offtop]Чтобы разобраться с выделением памяти нужно писать что-нибудь более компактное, ИМХО.[/offtop]
Ну это я параллельно, так сказать.
lanakramoleb вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Возникает ошибка при выделении памяти для элемента типа TStringList динамического массива записей. Вадим Мошев Общие вопросы Delphi 5 28.05.2011 10:48
Ошибка доступа при выделении памяти в чужом процессе Neoteric Общие вопросы Delphi 21 06.12.2010 16:50
выбор активной ячейки при выделении в listbox-e serafim09 Microsoft Office Excel 5 25.03.2010 10:37
Крупный глюк при выделении текста в Ворде motorway Microsoft Office Word 2 04.03.2010 16:17