今日、私はいくつかのsegfaults、スタックオーバーフロー、および解放された誤ったポインタエラーに当惑しました。
以前はマルチレベルポインタと関数パラメータの使用について少し混乱していましたが、今日は本当にいくつかの問題があります。
ここでは、mysqlから同じ条件で複数のデータを抽出し、1行
ずつ入力します... mysqlMsg * cur = NULL;を定義し、&curを使用して次の関数を渡し、curにメモリスペースを動的に割り当てます。
しかし、当然のことながら、私はこのメモリを使い始めました。
int mysqlGetMsgByUid(MYSQL mysql,int uid,mysqlMsg**mMsgList,int *mNum)
{
……
*(mMsgList)=malloc(num_rows*sizeof(mysqlMsg));
while(……){
(mMsgList[i])->id=atoi(row[0]);
(mMsgList[i])->type=atoi(row[1]);
(mMsgList[i])->send_id=atoi(row[2]);
strncpy((mMsgList[i])->message,row[3],MYSQL_MSG_SIZE);
(mMsgList[i])->status=atoi(row[4]);
(mMsgList[i])->flag=atoi(row[5]);
(mMsgList[i])->recv_id=uid;
i++;
}
……
}
実際、mMsgList [i]は*(mMsgList + i)と同等です。つまり、i×num_rows*sizeof(mysqlMsg)
このような大きな間隔を超え、i> 1の場合、割り当てた間隔サイズを超えます。
だから次のようになりました
free(): invalid pointer
已放弃 (核心已转储)
正しい操作は何ですか???
ダブルポインタは最初に逆参照され、次にi sizeof(mysqlMsg)によってオフセットされてから割り当てられます。
(*(mMsgList)+i)->id=atoi(row[0]);
(*(mMsgList)+i)->type=atoi(row[1]);
(*(mMsgList)+i)->send_id=atoi(row[2]);
strncpy((*(mMsgList)+i)->message,row[3],MYSQL_MSG_SIZE);
(*(mMsgList)+i)->status=atoi(row[4]);
(*(mMsgList)+i)->flag=atoi(row[5]);
(*(mMsgList)+i)->recv_id=uid;
もちろん、これは*mMsgList
、mMsgListの代わりにメモリスペースを割り当てたためです。そうでない場合、前の書き込みは正しいです。
また、char arglist[10][20]
このパラメーターは実際にはchar(* arglist)[20]の配列ポインターであるため、関数パラメーターとしてスタック領域に格納されている場合。次に、arglist [i]も配列を表します。このメモリをデータで満たすのに問題はなく、二重配列と直接交差することはありません。
ああ、しっかりとした基盤がとても重要です!