質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

Q&A

解決済

2回答

2244閲覧

gccでコンパイルした実行ファイルだとエラーが出ます。

akiya_0608

総合スコア14

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

0グッド

1クリップ

投稿2019/06/12 02:43

前提・実現したいこと

Windows環境で動作していたプログラムをマルチプラットフォーム対応のものに変換するべく、mac環境でgccを使用しコンパイルし実行ファイルを作成するところまではできたのですが、プログラムを実行すると途中でエラーが出て困っています。
ソースの説明を記述しておくと
mainではUDP_Serverのインスタンスの作成をしています。
UDP_ServevrのUpdateにはm_routine->Update(m_socket, U_recvDataQueList);とだけ記述しています。
この時のUpdateはUDP_Routine::Updateが呼び出されています。

発生している問題・エラーメッセージ

Server(35786,0x1116ea5c0) malloc: *** error for object 0x7ff0144035f0: pointer being freed was not allocated
Server(35786,0x1116ea5c0) malloc: *** set a breakpoint in malloc_error_break to debug
Abort trap: 6

該当のソースコード

C++

1>>main.cpp 2 std::shared_ptr<BaseServer> temp = UDP_Server::GetInstance("0.0.0.0", "12345", IPV4, false); 3 while (1) 4 { 5 temp->Update(); 6 if (temp->GetRecvDataSize() > 0) 7 { 8 return 0; 9 } 10 } 11 12////////////////////////////////////////////////////////////////////////// 13>>BaseServer.h 14class BaseServer 15{ 16public: 17 virtual ~BaseServer() { m_socket->Close(); } 18 virtual void Update(){}; 19 virtual int GetRecvDataSize() = 0; //クライアントから受信したデータがいくつあるか 20 virtual int SendOnlyClient(sockaddr_in *_addr, char *_buf, int _bufSize) { return 0; } //特定のクライアントに送信する場合使用する 21 virtual int SendMultiClient(std::vector<sockaddr_in> _addrList, char *_buf, int _bufSize) { return 0; } //特定の複数クライアントに送信する場合使用する 22 23 std::pair<sockaddr_in, std::vector<char>> UDP_GetRecvData(); //クライアントから受信したデータを取り出す 24 25protected: 26 std::shared_ptr<BaseSocket> m_socket; //ソケット通信用 27 std::shared_ptr<BaseRoutine> m_routine; //recv処理などのルーティン 28 static void SwitchIpv(std::shared_ptr<BaseSocket> _socket, int _ipv); //IPvの設定 29 30 std::queue<std::pair<sockaddr_in, std::vector<char>>> U_recvDataQueList; //クライアントから受信した情報が入る 31}; 32 33 34class UDP_Server : public BaseServer 35{ 36public: 37 UDP_Server() {} 38 ~UDP_Server() {} 39 static std::shared_ptr<BaseServer> GetInstance(const std::string _addrs, const std::string _port, const int _ipv, const bool _asynchronous = false); 40 virtual void Update() override; 41 virtual int GetRecvDataSize() override; //受信データの数を取得 42 virtual int SendOnlyClient(sockaddr_in *_addr, char *_buf, int _bufSize) override; //特定のクライアントに送信する場合使用する 43 virtual int SendMultiClient(std::vector<sockaddr_in> _addrList, char *_buf, int _bufSize) override; 44 45private: 46 unsigned int sequence = 0; //シーケンス番号 47}; 48 49>>BaseRoutine.cpp 50void UDP_Routine::Update(std::shared_ptr<BaseSocket> _socket, std::queue<std::pair<sockaddr_in, std::vector<char>>> &_recvDataQueList) 51{ 52 std::pair<sockaddr_in, std::vector<char>> addData; 53 char buf[TCP_BUFFERSIZE]; 54 55 //受信処理 56 57 int dataSize = _socket->Recvfrom(&addData.first, &buf[0], TCP_BUFFERSIZE, 0); 58 59 if (dataSize > 0) 60 { 61 62 addData.second.resize(dataSize); 63 std::memcpy(&addData.second[0], &buf[0], dataSize); 64 _recvDataQueList.push(addData); 65 } 66} 67

試したこと

UDP_Routine::Updateの_recvDataQueList.push(addData);が呼び出されたタイミングでエラーが出ているということまでは確認しました。

思いつく限りのことを試しましたがなぜエラーが出るのかがわかりません。
ご意見を頂けると幸いです。

補足情報(FW/ツールのバージョンなど)

環境:mac
コンパイラ:GCC 9.1.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

-fno-builtin-memcpyのコマンドオプションをつけると解決しました。
std::memcpyがgccのバージョンによって展開方法が少し違うみたいで、その制御をするコマンドオプションみたいです。

投稿2019/06/17 02:05

akiya_0608

総合スコア14

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

見たところソースに問題はないと思うので、
バッファーオーバーランかダングリングポインタによる領域破壊の類に見えます

プログラムすべてを疑っていかないといけないので大変ですが、
一応、以前私がとった対策だけ書いておきます

・配列はarrayに置き換える、以後長さが必要なときはarray.lengthを使う
→[]を使ってのアクセス時にassertしてくれる
→長さチェック時に、違う長さになってる事故が若干減る

・文字列はstringを使う

・deleteした後はNULLを入れる
shared_ptrやunique_ptrで直接ポインタを取り扱わない

投稿2019/06/13 09:43

izmktr

総合スコア2856

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問