Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2 3  Все   Вниз
  Печать  
Автор Тема: STL и MFC: выход за границы модуля и производительность  (Прочитано 56584 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« : 17-05-2008 07:48 » 

lapulya, вот ты сам и похоронил свою пламенную речь Ага
Цитата
...
замечено только одно место которое меня не устраивает, это передача объектов библиотеки через границу модуля и изменение этого объекта как раз в другом модуле
...

- а в MFC меня устраивает всё Улыбаюсь А шаблоны, как показала практика, не обязательны к применению
« Последнее редактирование: 21-05-2008 04:53 от Вад » Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #1 : 17-05-2008 10:51 » 

Дело твое (но повторюсь зря ты это...). Ну а через границу модуля я просто гоняю или константные объекты или приведенные с стандартныому виду (ну типа char * вместо std::string)
Записан

С уважением Lapulya
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #2 : 17-05-2008 15:11 » 

lapulya, в другой модуль просто указатель , мне кажется, передать и нельзя - только весь буфер. Если ошибаюсь - то ошибаюсь ))
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #3 : 17-05-2008 20:26 » 

Ну конечно ошибаешься, все модули работают в одном процессе => у них одно адресное пространство (ну это просто адресное пространство данного процесса), точнее что касается памяти у них все одинаково, поэтому передавая из модуля в модуль указатель на некую область памяти, получающий модуль совершенно запросто может читать и писать в память как по этому адресу, так и по любому другому ну ессесно в рамках дозволенного для данного процесса.
« Последнее редактирование: 17-05-2008 20:28 от lapulya » Записан

С уважением Lapulya
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #4 : 17-05-2008 21:06 » 

lapulya, ты же не уточнил, что у тебя за модули , я решил, что это именно разные процессы Улыбаюсь А в твоём случае можно, значит, даже нужно.  И с тем же CString это делается элементарно )
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #5 : 17-05-2008 21:21 » 

CString насколько мне известно не имеет реализации мемборов в *.h файлах, так что с ним никаких проблем при грамотном использовании быть не может.

Если я еще не все забыл то между процессами никакие буферы передавать нельзя (низзззя лазить в адресное пространство "чужого" процесса) для передачи между ними есть другие инструмент и их не мало (на форуме сие ужо обсуждалось, могу найти ссылки если надо)
Записан

С уважением Lapulya
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #6 : 17-05-2008 21:25 » 

lapulya, Лазить можно, винда это позволяет. Конечно, это не совсем стандартные средства, но они сушествуют.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #7 : 17-05-2008 21:28 » 

CString насколько мне известно не имеет реализации мемборов в *.h файлах

ещё как имеет. И h, и cpp

Если я еще не все забыл то между процессами никакие буферы передавать нельзя (низзззя лазить в адресное пространство "чужого" процесса) для передачи между ними есть другие инструмент и их не мало (на форуме сие ужо обсуждалось, могу найти ссылки если надо)

так я тебе это выше и говорил )
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #8 : 17-05-2008 21:33 » 

Алексей1153++, Скорее всего имелось ввиду такое:
CString.h
Код:
class CString
{
   ........
   int geLenght(void) {return lenght;}
   .........
};
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #9 : 17-05-2008 21:34 » 

Finch, в смысле ?
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #10 : 17-05-2008 21:36 » 

В самом описании класса описывается также и реализация функции. Как правило так описываются inline функции. Или шаблоные классы. Только я не совсем понимаю, почему это должно мешать в работе.
« Последнее редактирование: 17-05-2008 21:39 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #11 : 17-05-2008 21:41 » 

ничему это не помешает )

просто человек предвзято относится к MFC-классам
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #12 : 17-05-2008 22:02 » 

Алексей1153++, это как раз мешает, потому что для использования любого сласса (пусть и того же CString) в в конкретном модуле необходим include хеадера как минимум в cpp файл реализации этого модуля И если в этом хеадере есть реализация какой-то функции перераспределяющей память, то труба! (тут как раз и есть засада с std::string) при вызове этой функции в "неродном" модуле (не там где был создан объект) произойдет вызов new "чужого" модуля и тут может произойти все что угодно, вот поэтому я и спросил имеет ли CString реализацию функций перераспределяющей память в хеадере. Скорее всего не имеет, а если имеет, то этот класс в данном аспекте ни чем не лучше std::string.
Записан

С уважением Lapulya
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #13 : 18-05-2008 08:09 » 

Алексей1153++, это как раз мешает, потому что для использования любого сласса (пусть и того же CString) в в конкретном модуле необходим include хеадера как минимум в cpp файл реализации этого модуля И если в этом хеадере есть реализация какой-то функции перераспределяющей память, то труба! (тут как раз и есть засада с std::string) при вызове этой функции в "неродном" модуле (не там где был создан объект) произойдет вызов new "чужого" модуля и тут может произойти все что угодно, вот поэтому я и спросил имеет ли CString реализацию функций перераспределяющей память в хеадере. Скорее всего не имеет, а если имеет, то этот класс в данном аспекте ни чем не лучше std::string.

ни разу с подобными проблемами не сталкивался - ни заголовки не включал специально, ни проблем с new не было Улыбаюсь А MFC люди не глупые писали - в "h"-файлах реализацию вроде нигде не писали
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #14 : 18-05-2008 08:12 » 

вот описание CString из заголовочного файла

Код:
class CString
{
public:
// Constructors

// constructs empty CString
CString();
// copy constructor
CString(const CString& stringSrc);
// from a single character
CString(TCHAR ch, int nRepeat = 1);
// from an ANSI string (converts to TCHAR)
CString(LPCSTR lpsz);
// from a UNICODE string (converts to TCHAR)
CString(LPCWSTR lpsz);
// subset of characters from an ANSI string (converts to TCHAR)
CString(LPCSTR lpch, int nLength);
// subset of characters from a UNICODE string (converts to TCHAR)
CString(LPCWSTR lpch, int nLength);
// from unsigned characters
CString(const unsigned char* psz);

// Attributes & Operations

// get data length
int GetLength() const;
// TRUE if zero length
BOOL IsEmpty() const;
// clear contents to empty
void Empty();

// return single character at zero-based index
TCHAR GetAt(int nIndex) const;
// return single character at zero-based index
TCHAR operator[](int nIndex) const;
// set a single character at zero-based index
void SetAt(int nIndex, TCHAR ch);
// return pointer to const string
operator LPCTSTR() const;

// overloaded assignment

// ref-counted copy from another CString
const CString& operator=(const CString& stringSrc);
// set string content to single character
const CString& operator=(TCHAR ch);
#ifdef _UNICODE
const CString& operator=(char ch);
#endif
// copy string content from ANSI string (converts to TCHAR)
const CString& operator=(LPCSTR lpsz);
// copy string content from UNICODE string (converts to TCHAR)
const CString& operator=(LPCWSTR lpsz);
// copy string content from unsigned chars
const CString& operator=(const unsigned char* psz);

// string concatenation

// concatenate from another CString
const CString& operator+=(const CString& string);

// concatenate a single character
const CString& operator+=(TCHAR ch);
#ifdef _UNICODE
// concatenate an ANSI character after converting it to TCHAR
const CString& operator+=(char ch);
#endif
// concatenate a UNICODE character after converting it to TCHAR
const CString& operator+=(LPCTSTR lpsz);

friend CString AFXAPI operator+(const CString& string1,
const CString& string2);
friend CString AFXAPI operator+(const CString& string, TCHAR ch);
friend CString AFXAPI operator+(TCHAR ch, const CString& string);
#ifdef _UNICODE
friend CString AFXAPI operator+(const CString& string, char ch);
friend CString AFXAPI operator+(char ch, const CString& string);
#endif
friend CString AFXAPI operator+(const CString& string, LPCTSTR lpsz);
friend CString AFXAPI operator+(LPCTSTR lpsz, const CString& string);

// string comparison

// straight character comparison
int Compare(LPCTSTR lpsz) const;
// compare ignoring case
int CompareNoCase(LPCTSTR lpsz) const;
// NLS aware comparison, case sensitive
int Collate(LPCTSTR lpsz) const;
// NLS aware comparison, case insensitive
int CollateNoCase(LPCTSTR lpsz) const;

// simple sub-string extraction

// return nCount characters starting at zero-based nFirst
CString Mid(int nFirst, int nCount) const;
// return all characters starting at zero-based nFirst
CString Mid(int nFirst) const;
// return first nCount characters in string
CString Left(int nCount) const;
// return nCount characters from end of string
CString Right(int nCount) const;

//  characters from beginning that are also in passed string
CString SpanIncluding(LPCTSTR lpszCharSet) const;
// characters from beginning that are not also in passed string
CString SpanExcluding(LPCTSTR lpszCharSet) const;

// upper/lower/reverse conversion

// NLS aware conversion to uppercase
void MakeUpper();
// NLS aware conversion to lowercase
void MakeLower();
// reverse string right-to-left
void MakeReverse();

// trimming whitespace (either side)

// remove whitespace starting from right edge
void TrimRight();
// remove whitespace starting from left side
void TrimLeft();

// trimming anything (either side)

// remove continuous occurrences of chTarget starting from right
void TrimRight(TCHAR chTarget);
// remove continuous occcurrences of characters in passed string,
// starting from right
void TrimRight(LPCTSTR lpszTargets);
// remove continuous occurrences of chTarget starting from left
void TrimLeft(TCHAR chTarget);
// remove continuous occcurrences of characters in
// passed string, starting from left
void TrimLeft(LPCTSTR lpszTargets);

// advanced manipulation

// replace occurrences of chOld with chNew
int Replace(TCHAR chOld, TCHAR chNew);
// replace occurrences of substring lpszOld with lpszNew;
// empty lpszNew removes instances of lpszOld
int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew);
// remove occurrences of chRemove
int Remove(TCHAR chRemove);
// insert character at zero-based index; concatenates
// if index is past end of string
int Insert(int nIndex, TCHAR ch);
// insert substring at zero-based index; concatenates
// if index is past end of string
int Insert(int nIndex, LPCTSTR pstr);
// delete nCount characters starting at zero-based index
int Delete(int nIndex, int nCount = 1);

// searching

// find character starting at left, -1 if not found
int Find(TCHAR ch) const;
// find character starting at right
int ReverseFind(TCHAR ch) const;
// find character starting at zero-based index and going right
int Find(TCHAR ch, int nStart) const;
// find first instance of any character in passed string
int FindOneOf(LPCTSTR lpszCharSet) const;
// find first instance of substring
int Find(LPCTSTR lpszSub) const;
// find first instance of substring starting at zero-based index
int Find(LPCTSTR lpszSub, int nStart) const;

// simple formatting

// printf-like formatting using passed string
void AFX_CDECL Format(LPCTSTR lpszFormat, ...);
// printf-like formatting using referenced string resource
void AFX_CDECL Format(UINT nFormatID, ...);
// printf-like formatting using variable arguments parameter
void FormatV(LPCTSTR lpszFormat, va_list argList);

// formatting for localization (uses FormatMessage API)

// format using FormatMessage API on passed string
void AFX_CDECL FormatMessage(LPCTSTR lpszFormat, ...);
// format using FormatMessage API on referenced string resource
void AFX_CDECL FormatMessage(UINT nFormatID, ...);

// input and output
#ifdef _DEBUG
friend CDumpContext& AFXAPI operator<<(CDumpContext& dc,
const CString& string);
#endif
friend CArchive& AFXAPI operator<<(CArchive& ar, const CString& string);
friend CArchive& AFXAPI operator>>(CArchive& ar, CString& string);

// load from string resource
BOOL LoadString(UINT nID);

#ifndef _UNICODE
// ANSI <-> OEM support (convert string in place)

// convert string from ANSI to OEM in-place
void AnsiToOem();
// convert string from OEM to ANSI in-place
void OemToAnsi();
#endif

#ifndef _AFX_NO_BSTR_SUPPORT
// OLE BSTR support (use for OLE automation)

// return a BSTR initialized with this CString's data
BSTR AllocSysString() const;
// reallocates the passed BSTR, copies content of this CString to it
BSTR SetSysString(BSTR* pbstr) const;
#endif

// Access to string implementation buffer as "C" character array

// get pointer to modifiable buffer at least as long as nMinBufLength
LPTSTR GetBuffer(int nMinBufLength);
// release buffer, setting length to nNewLength (or to first nul if -1)
void ReleaseBuffer(int nNewLength = -1);
// get pointer to modifiable buffer exactly as long as nNewLength
LPTSTR GetBufferSetLength(int nNewLength);
// release memory allocated to but unused by string
void FreeExtra();

// Use LockBuffer/UnlockBuffer to turn refcounting off

// turn refcounting back on
LPTSTR LockBuffer();
// turn refcounting off
void UnlockBuffer();

// Implementation
public:
~CString();
int GetAllocLength() const;

protected:
LPTSTR m_pchData;   // pointer to ref counted string data

// implementation helpers
CStringData* GetData() const;
void Init();
void AllocCopy(CString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const;
void AllocBuffer(int nLen);
void AssignCopy(int nSrcLen, LPCTSTR lpszSrcData);
void ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data, int nSrc2Len, LPCTSTR lpszSrc2Data);
void ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData);
void CopyBeforeWrite();
void AllocBeforeWrite(int nLen);
void Release();
static void PASCAL Release(CStringData* pData);
static int PASCAL SafeStrlen(LPCTSTR lpsz);
static void FASTCALL FreeData(CStringData* pData);
}
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #15 : 18-05-2008 11:51 » 

Алексей1153++, вот смотри я говорил

Цитата: lapulya от Вчера в 19:21
Цитата
CString насколько мне известно не имеет реализации мемборов в *.h файлах

ты отвечал
Цитата
ещё как имеет. И h, и cpp

а теперь пишешь
Цитата
А MFC люди не глупые писали - в "h"-файлах реализацию вроде нигде не писали

Ну как же можно конструктивно вести дискуссию... Ну ладно скорее всего просто ты это пропустил, хотя все мои дальнейшие рассуждения были уже направлены на использование твоего мнения как эксперта по MFC (я так понимаю тут лучше тебя его никто не знает).

Ну а раз реализации в хеадере нет, то и проблем при передаче объекта через границу модуля нет (поэтому ты с ними и не сталкивался).
Записан

С уважением Lapulya
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #16 : 18-05-2008 12:23 » 

lapulya, а в чём противоречие то ? Улыбаюсь

я понял в таком смысле , что ты говоришь так - "нет реализации в файлах, есть где то в длл (например)" , поэтому так написал

и я вовсе не экперт MFC , Джон, например - вот это действительно эксперт Улыбаюсь

и всё равно не понятно, как связны такие вещи, как:
1) где находится реализация
2) возможность передачи указателя (ну или сразу тела объекта)

? Улыбаюсь
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #17 : 18-05-2008 12:55 » 

Если класс имеет реализацию функций в хеадере И эта реализация перераспределяет память (ну там буфер увеличивает, типа старый маленький освобождает, а новый большой выделяет), то тут таятся большие грабли. Вчем собственно грабли - для использования объекта этого класса в другом модуле (например, в другой dll), необходимо как минимум в cpp файле этого "другого модуля (для определенности назовем его dll)" сделать includ хеадера описывающего этот класс (ну тут все я сно - хотим в реализации dll использовать объект какого-то класса, для определенности пусть будет CString, значит нужен инклуд хеадера, в котором описан класс CString). Далее - если в cpp файла этой dll у объекта типа CString идет вызов той самой функции, которая перераспределяет память И (не забываем) эта функция имеет реализацию в хеадере, то понятное дело что произойдет вызов и delete и new определенных в dll (при компоновке dll вся реализация кода этой dll, естественно включая реализацию всех функций описанных в хеадерах, которые инклудятся в dll - будет своя!!!!).

И что же в итоге мы имеем, а то что буфер у объекта CString был изначально создан в первом модуле (для определенности в exe), потом сам объект был передан через границу модуля в dll, там (уже в dll) этот буфер освобождается (при вызове функции перераспределяющей память, при этом отрабатывает delete dll) и вуаля.... ЖОПА!!! Ну а дальше она просто усугубится поскольку новый буфер быделяется new из dll, а потом освобождается delete в exe. На самом деле уже первая жопа потенциально форматирует винт.
« Последнее редактирование: 18-05-2008 12:56 от lapulya » Записан

С уважением Lapulya
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #18 : 18-05-2008 13:05 » 

lapulya, возможно, я просто тупой, но я так и не понял твоей проблемы. Во первых - не делай в хедере реализаций , во вторых - не делай выделение и удаление в разных местах, и будет щастье Улыбаюсь
Указатель обычно передают не для того, чтоб там где то удалить буфер, на который указатель указывает, а чтобы этот буфер скопировать
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #19 : 18-05-2008 13:27 » 

проблема в том что stl имеет всю реализацию внутри хеадера и при передаче неконстантного объекта через границу модуля (и изменения этого объекта в чужем модуле) будут проблемы.

А у меня проблемы нет, я только объяснял вот это
Цитата
Ну а через границу модуля я просто гоняю или константные объекты или приведенные с стандартныому виду (ну типа char * вместо std::string)

Кстати, указатель передают, чтобы с буфером поработать (т.е. и читать и писать, но не меняя его размеров, да и то не факт...), а вот константный буфер передают как раз только для чтения.
« Последнее редактирование: 18-05-2008 13:30 от lapulya » Записан

С уважением Lapulya
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #20 : 18-05-2008 13:36 » 

lapulya, я же объяснял, что объект я тут же удаляю
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #21 : 18-05-2008 14:15 » 

да какая разница. Если память хоть раз была выделена в одном модуле, а потом в другом освобождена, все )))) винт отформатирован ))))))
Записан

С уважением Lapulya
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #22 : 18-05-2008 14:32 » 

Цитата
Если память хоть раз была выделена в одном модуле, а потом в другом освобождена,

во-первых, нормальный программист так не делает, если только прям прижало (да и то, для этого другие механизмы использоваться должны)
во-вторых, к форматированию это не приведёт. Сделай такую штуку нарочно - и я поверю, что это может случайно произойти, да и то, если природа ошибки будет одинакова Улыбаюсь
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #23 : 18-05-2008 15:16 » 

1) вот если прижало и он так сделал, то и получит на орехи
2) да легко, писать не буду долго подгадывать, а вот суть в псевдо коде такая, допустим у тебя есть в программе кусок, который стирает определенный файл, естественно делаются все проверки и т.д.

if (есловие)
removeFile(определенный)

при запуске программы исходный код смаппирован в память, при освобождении чужого участка памити и трешь ту область где идут проверки и пишешь в нее строку, которая в допустим там начинается условно с 1, получаем так

if (true || .... )

и имяфайла меняем на *, в итеге имеем

if (1)
removeFile(*);

очень условно, но смысл должен быть понятен, более того, может так сложиться есть у тебя строка которая будучи смапирована в память просто будет ассемблерным кодом функции форматирующей винт, соответсвенно если в рантайме исправить представление printf ("Hello word"); на эту и получишь, то что хочешь. Я ж уже рассказывал дважды как в рантайме!!! (прога уже работает) изменить функцию обработки сообщений, вот это наглядный пример того, как можно изменив кусок памяти в рантайме и кардинально поменять логику выполнения программы.
Записан

С уважением Lapulya
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #24 : 18-05-2008 17:10 » 

Код:
при освобождении чужого участка памити и трешь ту область где идут проверки и пишешь
процессор не даст изменить сегмент кода

Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #25 : 18-05-2008 18:20 » 

Во первых код в динамике менять можно (я ж сказал что могу функцию обработки окна сменить), а во-вторых причем тут процессор?
Записан

С уважением Lapulya
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #26 : 18-05-2008 19:07 » 

lapulya, процессор при том, что есть сегменты кода, стека и данных , разделение которых в x86 поддерживается на аппаратном уровне

чтобы поменять из программы содержимое сегмента кода, надо приложить усилия (какие - точно не знал , да и забыл, как говорится Отлично ) , а кроме того может взбрыкнуть антивирус Улыбаюсь . Хотя последний тут практически ни при чём , те самые усилия случайно не получатся, как следствие изменения буфера строки, например
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #27 : 18-05-2008 19:59 » 

lapulya, Ой, куда тебя не туда занесло. В конечном счете все действия оператора new сводятся к вызову функции malloc. Все действия оператора delete сводятся к вызову  free. Для Linux будет все равно откуда вызвано, все равно будет обрашение к библиотеке стандартных функций  libc.
Какие я вижу вообше подножки в этом: Оператор new можно переопределить и занести Какие либо свои структуры в выделяемый участок памяти. Естественно другой delete, который не обучен этому, просто напросто не сможет удалить данный участок памяти. Последствия этого течь памяти.
ּВ винде память для программ выделяется в специальных участках памяти, называемых куча. Если delete  начнет удалять в не своей куче, просто напросто, он не найдет соответствуюший адрес в своих таблицах, и просто не удалит его. Как следствие течь памяти.
В принципе я не совсем понимаю, почему должна быть разница, где описан код, с работой с динамической памятью. По любому случаю, в окончательном объектном файле будет просто линк на функции malloc и free стандартной библиотеки.
« Последнее редактирование: 18-05-2008 20:23 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #28 : 19-05-2008 05:28 » 

Finch, попробуй взять std::string
напиши dll которая которая будет заполнять строку например 1000 символов интерфейс вот такой
extern "C"
{
void foo(std::string &);
}

теперь напиши exe который будет вызвать функцию библиотеки.

библиотеку компилируй в VC++, а exe компилируй в gcc

{
   std::string s;
   foo(s);
}

у меня была ошибка обращения к памяти, лечил предварительным резервирование буфера в строке что бы не было аллокации в библиотеке

использовал std::string из STLport

куча то у всех конечно одна, но вот только операторы new/delete не обязательно явно делают malloc, они могу делать еще какую-то работу

Хотя всё это давно было я тогда только начинал программировать и VC++ была старенькая, фиг знает, какая заточка есть у STLPort от VS 6.0.
Записан

Странно всё это....
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #29 : 19-05-2008 07:58 » 

Finch, Дискутировать на эту тему даже не буду ибо... ээээх...
Короче проблемы будут... вот..., если не верится надо книжки почитать (да в баню книжки..., просто Страуструпа взять и про new и его переопределение почитать, или Рихтера, там тоже есть)

Ладно, поясню, реализация new  в одном модуле (да через malloc и т.д.), НО тут вопрос сколько выделить и как использовать, допустим для оптимизации работы с памятью или для отслеживания утечек (или по еще 1000 причин) реализация new для int выделяет не 4 а допустим 6 или 8 или 10 байт, то и освобождение памяти будет такоеже т.е. соответственно 6, 8 или 10 байт. А в другом модуле типа все стандартно, т.е. для int выделяется и освобождается 4 байта.

Ну и теперь простой вопрос, что будет если память выделялать в модуле где под int выделяется 4 байта, а освобождается в модуле где под int отводится 10 байт... а для масштабов бедствия можно представить, что это был массив из 10000 элементов...
Записан

С уважением Lapulya
Страниц: [1] 2 3  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines