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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 27.06.2012, 03:30   #1
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию как подружить std::map и глобальные объекты

Проверял под студией и QtCreator. Mingw прожевал, а вот студийный компиль (2008) вывалился в рантайме: "не обработанное исключение".
А мне нужно поддерживать с ним совместимость.

В чем здесь может быть причина проблемы?

//CTest.h
Код:
#ifndef CTEST_H
#define CTEST_H

class CTest
{
public:
    CTest();
    ~CTest();
    int a;
};

#endif // CTEST_H


//CTest.cpp
Код:
#include "CTest.h"
#include<map>

using namespace std;

namespace CTestSpase
{
    map<int,int> gMap; 
}
using namespace CTestSpase;

CTest::CTest()
{
    gMap[100] = 10;  //крешется в его недрах. Винда выбрасывает окно "необработанное исключение"
}

CTest::~CTest(){}



//main.cpp
Код:
#include "CTest.h"
CTest test;

int main()
{
   return 0;
}
С vector/list проблем нет. А вот map, или set ломается при попытки попользовать в конструкторе класса глобальный объект
Если модифицировать глобальный объект не в конструкторе, а в методе - проблем нет.

Есть подозрение, что это может быть связанно как то с "неопределенным порядком инициализации единиц трансляции". Но вот в чем на самом деле собака зарыта?
И можно ли это как нибудь вылечить?
_Bers вне форума Ответить с цитированием
Старый 27.06.2012, 03:56   #2
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Совершенно верно, причина падения - "неопределённый порядок инициализации единиц трансляции". gcc тоже падать должен, если порядок файлов-исходников поменять (поставить main.cpp первым). Каких-нибудь извращений понапридумывать можно, но лучше подыскать другой способ реализации задуманного, так как это будет всё равно компиляторо-зависимо и небезопасно, без каких-либо гарантий.
netrino вне форума Ответить с цитированием
Старый 27.06.2012, 09:06   #3
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

А почему std::vector не ломается при аналогичном использовании?
_Bers вне форума Ответить с цитированием
Старый 27.06.2012, 10:44   #4
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

_Bers

Но вот в чем на самом деле собака зарыта?

C++ std, 3.6.2

И можно ли это как нибудь вылечить?

Паттерн Singleton

А почему std::vector не ломается при аналогичном использовании?

У него более светлая карма oO
Rififi вне форума Ответить с цитированием
Старый 27.06.2012, 11:15   #5
Last
В прострации
Форумчанин
 
Регистрация: 13.01.2009
Сообщений: 239
По умолчанию

Может попробовать вставку с помощью gMap.insert?
Пол-жизни сидючи, в монитор глядючи...
Last вне форума Ответить с цитированием
Старый 27.06.2012, 13:01   #6
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2_Bers
как вариант, инициализировать мап раньше (точнее, отложить инициализацию).
Код:
#include "CTest.h"
#include<map>

using namespace std;

namespace CTestSpase
{
    extern map<int,int> gMap; 
}
using namespace CTestSpase;

CTest::CTest()
{
    gMap[100] = 10;  //крешется в его недрах. Винда выбрасывает окно "необработанное исключение"
}

CTest::~CTest(){}
Код:
#include "CTest.h"
#include <map>

namespace CTestSpase
{
    map<int,int> gMap; 
}

CTest test;

int main()
{
   return 0;
}
естественно это не оптимально. синглтон уже предлагали
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 27.06.2012 в 21:47.
pproger вне форума Ответить с цитированием
Старый 27.06.2012, 19:48   #7
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Rififi Посмотреть сообщение
C++ std, 3.6.2
Это я уже как бэ понял. Теперь хочу понять, как сделать безопасный код.

Цитата:
Сообщение от Rififi Посмотреть сообщение
Паттерн Singleton
В настоящий момент конфликт разрешен за счет механизма, применяемого в "классическом одиночке". Однако, задача одиночки - гарантировать единственность объекта. В его задачи не входит разрешать конфликты глобальных/статических данных. С одной стороны, использование одиночки не по назначению ухудшает комфортность написания кода и сопровождения. А с другой...

std::vector, std::list, стримы (std::cout/std::cin) не являются одиночками, однако, никаких сложностей с "глобальностью" не испытывают.

Цитата:
Сообщение от Rififi Посмотреть сообщение
А почему std::vector не ломается при аналогичном использовании?

У него более светлая карма oO
Есть предположение, что строение этого класса имеет защиту от подобных проблем. И если понять принцип её действия, то можно будет писать безопасный код.
_Bers вне форума Ответить с цитированием
Старый 27.06.2012, 21:01   #8
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2_Bers
Цитата:
std::vector, std::list, стримы (std::cout/std::cin) не являются одиночками, однако, никаких сложностей с "глобальностью" не испытывают.
если прога не сегфолтится, это не значит, что проблем нет

A.h
Код:
#ifndef _A_H
#define _A_H

class A {
public:
	A();
	void foo();
};
#endif
A.cpp
Код:
#include "A.h"
#include <vector>
#include <iostream>

using namespace std;

vector<int> v;

A::A()
{
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(6);
	v.push_back(7);
	v.push_back(8);
	v.push_back(9);
}

void A::foo()
{
	cout << v.size() << endl;
}
main.cpp
Код:
#include <iostream>
#include "A.h"

using namespace std;

A a;

int main()
{
	a.foo();
	return 0;
}
что выведет?
пс. да, если компилять конечно как g++ A.cpp main3.cpp (т.е чтоб A.cpp был первым)

Цитата:
Есть предположение, что строение этого класса имеет защиту от подобных проблем. И если понять принцип её действия, то можно будет писать безопасный код.
вот читаю это и вспоминается фраза одного человека - you are full of bullshit(c)
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 27.06.2012 в 21:07.
pproger вне форума Ответить с цитированием
Старый 27.06.2012, 21:06   #9
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

вывел ноль
_Bers вне форума Ответить с цитированием
Старый 27.06.2012, 21:08   #10
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2_Bers
Цитата:
вывел ноль
еще утверждаешь, что проблем с вектором в этом случае нет?
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как подружить Ribbon и Alpha Controls artemavd Компоненты Delphi 0 17.06.2012 17:44
Как грамотно подружить Firebird и Interbase на 1 ПК? Alexei91 БД в Delphi 3 20.08.2010 13:29
Исключение при удалении из std::map arokot Общие вопросы C/C++ 2 11.08.2010 17:36
сортировка std::map NiCola999 Общие вопросы C/C++ 2 27.04.2010 23:14
Как подружить SendMessage и TIdHTTP zcoder Работа с сетью в Delphi 1 13.04.2009 06:01