Aujourd'hui, j'ai été gêné par plusieurs segfaults, des débordements de pile et des erreurs de pointeur incorrectes gratuites.
J'étais un peu confus à propos de l'utilisation des pointeurs multi-niveaux + des paramètres de fonction, mais aujourd'hui j'ai vraiment quelques problèmes.
Ici, je veux extraire plusieurs données avec les mêmes conditions de mysql, remplissez-les simplement ligne par ligne ...
définissez un mysqlMsg * cur = NULL; puis utilisez & cur pour passer la fonction suivante pour allouer dynamiquement de l'espace mémoire pour cur.
Mais j'ai commencé à utiliser ce morceau de mémoire comme une évidence.
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++;
}
……
}
En fait, mMsgList [i] équivaut à * (mMsgList + i), c'est-à-dire qu'il traverse i×num_rows*sizeof(mysqlMsg)
un si grand intervalle, et quand i> 1, il dépasse la taille de l'intervalle que nous allouons.
Donc ce qui suit est apparu
free(): invalid pointer
已放弃 (核心已转储)
Quelle est l'opération correcte? ? ?
Le double pointeur est d'abord déréférencé, puis décalé de i sizeof (mysqlMsg), puis attribué.
(*(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;
Bien sûr, c'est parce que j'ai *mMsgList
alloué de l'espace mémoire au lieu de mMsgList, sinon l'écriture précédente est correcte
Et s'il est stocké dans la zone de pile en char arglist[10][20]
tant que paramètre de fonction, car ce paramètre est en réalité un pointeur de tableau de char (* arglist) [20]. Alors arglist [i] représente également un tableau, il n'y a aucun problème à remplir cette mémoire avec des données, il ne traversera pas directement un tableau double.
Ah, une base solide est très importante!