我得到一個「*錯誤在`./chatty':munmap_chunk():無效指針:0x000000000040635f *」每當我調試這段代碼(在交換機的情況下REGISTER_OP後),在「free(replySnd)」的調用下,在我粘貼在下面的代碼片段的末尾(從底部開始第12行),我只是不明白爲什麼它發生,因爲指針不應該是靜態的因爲我使用的是strdup(我已經嘗試使用malloc分配內存,然後將內容複製到它中,結果相同)核心轉儲免費通話
我粘貼了整個函數,以便您可以查看每次使用變量replySnd,我發佈了setHeader和setData函數的定義。
我注意到,我導致一個核心轉儲執行任何這些免費的,而不是隻有第一個。
void* workerFunction(void* arg) {
/* Estraggo i parametri passati */
workerparam* params = (workerparam*)arg;
usertable_t* usrTbl = params->table;
struct statistics* chatStats = params->stats;
pthread_mutex_t* statsMux = params->mux;
size_t maxMsgSize = params->msgSize, maxFileSize = params->fileSize;
int tmp;
request_t* req;
message_t* reply;
op_t replyOp;
char* replySnd;
char* replyRcv;
char* replyBuf;
unsigned int replyBufLen;
userdata_t* tmpUsr;
int replyFd;
int nonDeall, toSend;
printf("Worker: Initialized\n");
for (;;) {
reply = (message_t*)malloc(sizeof(message_t*));
if(!reply) perror("malloc");
replyBuf = NULL;
replyBufLen = 0;
toSend = 1;
nonDeall = 0;
/* Ottengo la richiesta da eseguire */
req = reqPop();
if (!req) perror("reqPop");
printf("Worker: Got a request (OP=%d)\n", req->op);
replyFd = req->fd;
/* Eseguo un controllo sul tipo di operazione */
switch (req->op) {
case REGISTER_OP: {
replySnd = "";
if (strlen(req->sname) == 0) {
replyRcv = "";
replyOp = OP_FAIL;
incErrors(chatStats, statsMux);
} else if ((tmp =usertable_isRegistered(usrTbl, (req->sname))) == -1) {
replyRcv = "";
perror("isRegistered");
replyOp = OP_FAIL;
incErrors(chatStats, statsMux);
} else if (tmp == 1) {
replyRcv = "";
replyOp = OP_NICK_ALREADY;
incErrors(chatStats, statsMux);
} else { // Inserisco il nuovo utente
replyRcv = strdup(req->sname);
tmpUsr = userdata_create();
if(!tmpUsr) perror("userdata_create");
strcpy((tmpUsr->name), (req->sname));
tmpUsr->isOnline = 1;
tmpUsr->lastFd = req->fd;
usertable_insert(usrTbl, tmpUsr);
replyOp = OP_OK;
incRegistered(chatStats, statsMux);
incOnline(chatStats, statsMux);
replyBuf = usertable_getOnlineUsersAsString(usrTbl, &replyBufLen);
}
} break;
case CONNECT_OP: {
replySnd = "";
if (strlen(req->sname) == 0) {
replyRcv = "";
replyOp = OP_FAIL;
incErrors(chatStats, statsMux);
} else if ((tmp =usertable_isRegistered(usrTbl, (req->sname))) == -1) {
replyRcv = "";
perror("isRegistered");
replyOp = OP_FAIL;
incErrors(chatStats, statsMux);
} else if (tmp == 0) {
replyRcv = "";
replyOp = OP_NICK_UNKNOWN;
incErrors(chatStats, statsMux);
} else { // Inserisco il nuovo utente
replyRcv = strdup(req->sname);
if (usertable_setOnline(usrTbl, replyRcv, replyFd) < 0) {
perror("setOnline");
replyOp = OP_FAIL;
incErrors(chatStats, statsMux);
} else {
replyOp = OP_OK;
incOnline(chatStats, statsMux);
replyBuf = usertable_getOnlineUsersAsString(usrTbl, &replyBufLen);
}
}
} break;
case POSTTXT_OP: {
replySnd = strdup(req->sname);
replyRcv = strdup(req->rname);
if(!replySnd || !replyRcv || strlen(replySnd) == 0 || strlen(replyRcv) == 0) {
replyOp = OP_FAIL;
} else if (usertable_isOnline(usrTbl, replySnd) != 1 || usertable_isRegistered(usrTbl, replyRcv) != 1) {
replyOp = OP_NICK_UNKNOWN;
} else if (req->size > maxMsgSize) {
replyOp = OP_MSG_TOOLONG;
} else {
nonDeall = 1;
replyOp = TXT_MESSAGE;
replyBuf = strdup(req->msg);
replyBufLen = req->size;
}
} break;
}
/* Creo il messaggio */
setHeader(&(reply->hdr), replyOp, replySnd);
setData(&(reply->data), replyRcv, replyBuf, replyBufLen);
if (replyOp == TXT_MESSAGE) {
tmp = usertable_addMessage(usrTbl, replyRcv, reply);
if (tmp < 0) perror("internal usertable inconsistency");
if (tmp == 0) { /* Receiver Offline */
incTxtNonDel(chatStats, statsMux);
toSend = 0;
} else { /* Receiver Online */
incTxtDel(chatStats, statsMux);
toSend = 1;
}
}
if(toSend) {
/* Invio il messaggio */
if (sendResponse(replyFd, reply) < 0) perror("sendResponse");
}
if(!nonDeall) {
/* Libero la memoria allocata */
free(replySnd);printf("Worker: I GOT HERE snd\n");
free(replyRcv);printf("Worker: I GOT HERE rcv\n");
free(replyBuf);printf("Worker: I GOT HERE buf\n");
free(reply);printf("Worker: I GOT HERE reply\n");
}
//TODO Implementare invio, gestione msginviati, sendatata aggiuntivo e deallocamento pointers
}
return NULL;
的setHeader功能代碼:
static inline void setHeader(message_hdr_t *hdr, op_t op, char *sender) {
#if defined(MAKE_VALGRIND_HAPPY)
memset((char*)hdr, 0, sizeof(message_hdr_t));
#endif
hdr->op = op;
strncpy(hdr->sender, sender, strlen(sender)+1);
}
使用setData功能:
static inline void setData(message_data_t *data, char *rcv, const char *buf, unsigned int len) {
#if defined(MAKE_VALGRIND_HAPPY)
memset((char*)&(data->hdr), 0, sizeof(message_data_hdr_t));
#endif
strncpy(data->hdr.receiver, rcv, strlen(rcv)+1);
data->hdr.len = len;
data->buf = (char *)buf;
}
我花了太多的時間試圖找到這個bug
選擇LANGUAG。如果它是C,你可以擺脫那些石膏 –
解決這些問題的正確工具是你的調試器。在*堆棧溢出問題之前,您應該逐行執行您的代碼。如需更多幫助,請閱讀[如何調試小程序(由Eric Lippert撰寫)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。至少,你應該[編輯]你的問題,以包含一個[Minimal,Complete,and Verifiable](http://stackoverflow.com/help/mcve)例子來重現你的問題,以及你在調試器中所做的觀察。 –
使用[valgrind](http://www.valgrind.org),你會很快發現問題。 –