Форум программистов, компьютерный форум CyberForum.ru

Как это работает? - C++

Восстановить пароль Регистрация
 
defer
秘密
 Аватар для defer
555 / 235 / 3
Регистрация: 29.11.2010
Сообщений: 783
25.06.2012, 23:35     Как это работает? #1
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <cstring>
using namespace std;
 
int main()
{
    char* s=new char[100];
    s="Jonessssssssssssssssssssssss";
    char* l =new char[100];
    l="Doe";
 
    l=s;
    cout << s << endl;
    cout << l << endl;
 
    delete[] s;
    delete[] l;
 
    char* d=new char[100];
    d=l;
    cout << d << endl;
    cout << sizeof s << endl;
    cout << l << endl;
    return 0;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
LEQADA
Мастер кустарных методов
 Аватар для LEQADA
227 / 222 / 9
Регистрация: 09.11.2010
Сообщений: 680
25.06.2012, 23:54     Как это работает? #2
На GCC 4.6.1 не компилируется из-за предупреждений.
deprecated conversion from string constant to <char*> [-Wwrite-strings]
alsav22
5284 / 4803 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
25.06.2012, 23:59     Как это работает? #3
Цитата Сообщение от defer Посмотреть сообщение
delete[] s;
delete[] l;
Рано удаляешь.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 51
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
26.06.2012, 00:01     Как это работает? #4
Тут в принципе удалять нельзя, вообще не верная работа с динамической памятью.
defer
秘密
 Аватар для defer
555 / 235 / 3
Регистрация: 29.11.2010
Сообщений: 783
26.06.2012, 00:03  [ТС]     Как это работает? #5
Цитата Сообщение от LEQADA Посмотреть сообщение
На GCC 4.6.1 не компилируется из-за предупреждений.
Компилируется и с -Wall и с-Pedantic-errors


Цитата Сообщение от alsav22 Посмотреть сообщение
Рано удаляешь.
вопрос: почему работает?
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 51
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
26.06.2012, 00:09     Как это работает? #6
Цитата Сообщение от defer Посмотреть сообщение
char* s=new char[100];
Здесь выделяется память в 100 байт, и адрес первого байта присваивается указателю.
Вот тут
Цитата Сообщение от defer Посмотреть сообщение
s="Jonessssssssssssssssssssssss";
указатель меняет свое значение, и начинается указывать на строковый литерал. Мало того, что теряется выделенная память 100 байт, что приводит к утечке, так еще и указатель не-const, что приводит к неопределенному поведению, так как строковый литерал сам по себе константный.
А вот тут скорей всего будет crash:
C++
1
2
delete[] s;
delete[] l;
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
26.06.2012, 00:10     Как это работает? #7
Цитата Сообщение от defer Посмотреть сообщение
вопрос: почему работает?
потому что везет, хотяяя

Bash
1
2
3
Jonessssssssssssssssssssssss
Jonessssssssssssssssssssssss
memory clobbered before allocated block
Добавлено через 1 минуту
я почти уверен, что если MALLOC_CHECK_ выставить в двойку, то программа радостно грохнется
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 51
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
26.06.2012, 00:10     Как это работает? #8
Цитата Сообщение от defer Посмотреть сообщение
Компилируется и с -Wall и с-Pedantic-errors
Тут, скорей всего, имелось ввиду с -Werror.
alsav22
5284 / 4803 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.06.2012, 00:17     Как это работает? #9
Из-за delete виснет.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
26.06.2012, 00:26     Как это работает? #10
код неправильный - это очевидно
смысл обсуждать последствия
defer
秘密
 Аватар для defer
555 / 235 / 3
Регистрация: 29.11.2010
Сообщений: 783
26.06.2012, 00:27  [ТС]     Как это работает? #11
Цитата Сообщение от alsav22 Посмотреть сообщение
Из-за delete виснет.
какой компилятор?

Добавлено через 43 секунды
Цитата Сообщение от alex_x_x Посмотреть сообщение
код неправильный - это очевидно
смысл обсуждать последствия
Проблема в том, что он работает
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 51
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
26.06.2012, 00:29     Как это работает? #12
Вам уже сказали, что это всего лишь дело случая. Вам просто повезло, у данного кода неопределенное поведение, оно может быть каким угодно.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
26.06.2012, 00:30     Как это работает? #13
Цитата Сообщение от defer Посмотреть сообщение
Проблема в том, что он работает
в чем проблема?
стандарт на такое говорит, что после таких действий программа может отформатировать ваш винчестер и будет права
undefined behavior и ее никто не ограничивает
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 51
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
26.06.2012, 00:30     Как это работает? #14
Вот можете посмотреть, что происходит на gcc 4.7.1. Да и на нем при определенных условиях возможна "правильная" работа, тут не столько от компилятора, сколько, опять же, от случая зависит.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.06.2012, 00:59     Как это работает?
Еще ссылки по теме:

C++ Простые числа, или как это работает?
как все это в подробностях работает? C++
C++ Как это работает?
C++ Как это работает?
Функция printf () как это работает C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
tihonya
11 / 7 / 1
Регистрация: 30.05.2012
Сообщений: 107
26.06.2012, 00:59     Как это работает? #15
Вот немного подправил , здесь можно удалять, все будет работать.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <cstring>
using namespace std;
 
int main()
{
    char* s=new char[100];
    strcpy(s,"Jonessssssssssssssssssssssss");
    char* l =new char[100];
    strcpy(l,"Doe");
//    l=s;   //?? Адресу указателя l присваевается адрес указателя s 
    //тоесть два указателя указывают на одну и туже ячейку дважды  delete не пройдет
    cout << s << endl;
    cout << l << endl;
 
    delete[]s;
 //   delete[]l;
 
    char* d;//=new char[100];
    d=l;
    cout << d << endl;
    cout << sizeof s << endl;
    cout << l << endl;
    delete[]d; //  l мы удалили тоже
return 0;
 
}
нужно использовать strcpy для инициализации строковых переменных. и если присваивать указатель указателю d=l; то не обязательно выделять сразу под него память.
Yandex
Объявления
26.06.2012, 00:59     Как это работает?
Ответ Создать тему
Опции темы

Текущее время: 18:47. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru