Я использовал #pragma pack(push, 2)
в начале структуры в заголовочном файле, но забыл соответствующий #pragma pack(pop)
. После включения этого заголовочного файла я включил fstream. При создании объекта ofstream
я вижу разрушение стека. Подробности точного сценария и кода следующие:
Я проходил курс C ++ и написал код для проекта. Моя программа зависала из-за разрушения стека. Я пытался найти какие-либо очевидные ошибки переполнения, но не смог их найти. Я изменил почти весь мой код, чтобы он напоминал код, предоставленный инструктором. Единственная разница заключается в порядке включения заголовочных файлов. Я включил заголовочные файлы, за которыми следовал fstream
, в то время как инструктор включил заголовочный файл fstream
вверху. Тем не менее я получал ту же проблему. Поэтому я изменил даже порядок заголовочных файлов и вуаля, проблема исчезла.
Поскольку это было странно для меня, я попытался локализовать проблему в своем коде.
Я вставил операторы печати по всему коду, чтобы найтифункция, где происходило разрушение стека.
Найдя функцию, я использовал gdb, чтобы установить отслеживание канареечного значения, используемого моей программой для проверки разрушения стека. Я обнаружил разрушение стека в конструкторе объекта ofstream
.
В этот момент я знал, что какой-то заголовочный файл, включенный до того, как fstream
мешал ему. Итак, теперь я проверил все мои заголовочные файлы на наличие каких-либо глупых ошибок и обнаружил структуру, которой предшествует #pragma pack(push, 2)
, но за которой не следует соответствующая #pragma pack(pop)
. Эта структура должна была быть записана в виде двоичного файла. Исправление этой проблемы решило проблему.
Поскольку весь проект не имеет значения, я воспроизвел проблему с помощью простого фрагмента кода. Хотя проблема решена, я хотел бы знать, почему это произошло. Я понимаю, что директива pragma pack
использовалась для того, чтобы компилятор не вставлял отступы внутри структуры, так как структура должна была быть записана в двоичный файл. Пропуск pack(pop)
в конце структуры использует то же самое для всех последующих заголовочных файлов. Но может ли это привести к тому, что конструктор ofstream будет писать поверх фрейма стека?
Я использую gcc v7.4.0 в Ubuntu 18.04.
/* code.cpp */
#include "header.h"
#include <fstream>
using namespace std;
int main(){
ofstream fout;
fout.open("file.ext", ios::out|ios::binary);
fout.close();
return 0;
}
Файл заголовка
#ifndef HEADER_H_
#define HEADER_H_
#pragma pack(push, 2)
struct something{
int a;
};
//#pragma pack(pop)
//Uncommenting the above line solves the problem
#endif