Ich erhalte einen "* Fehler in` ./chatty ': munmap_chunk(): ungültige Zeiger: 0x000000000040635f *" wenn ich debuggen dieses Stück Code (nach dem Fall REGISTER_OP am Schalter), beim Aufruf von "free (replySnd)", um das Ende des Stückes Code, das ich unten eingefügt habe ... (12. Reihe von unten), verstehe ich einfach nicht, warum es passiert, da der Zeiger nicht statisch sein sollte wie ich benutze strdup (ich habe bereits versucht, Speicher zuweisen mit malloc und dann kopieren Sie den Inhalt in sie, und das Ergebnis war das gleiche)Core-Dump auf kostenlosen Anruf
Ich klebte die ganze Funktion, so dass Sie einen Blick auf jede Verwendung der haben Variable replySnd, und ich poste die Definition der Funktionen setHeader und setData.
Mir ist aufgefallen, dass ich einen Core-Dump verursache, der irgendeinen von diesen frei ausführt, nicht nur mit dem ersten.
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 Funktionscode:
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 Funktion:
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;
}
Ich habe viel zu viele Stunden damit, diesen Fehler finden
die languag wählen. Wenn es C ist, können Sie diese Umwandlungen loswerden –
Das richtige Werkzeug, um solche Probleme zu lösen, ist Ihr Debugger. Sie sollten Schritt für Schritt durch Ihren Code * gehen, bevor Sie auf Stack Overflow nachfragen. Für weitere Hilfe lesen Sie bitte [Wie kleine Programme zu debuggen (von Eric Lippert)] (https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). Zumindest sollten Sie Ihre Frage so bearbeiten, dass sie ein [minimales, vollständiges und überprüfbares] (http://stackoverflow.com/help/mcve) Beispiel enthält, das Ihr Problem zusammen mit den Beobachtungen, die Sie im Debugger gemacht haben, reproduziert . –
Verwenden Sie [Valgrind] (http://www.valgrind.org), und Sie werden das Problem sehr schnell finden. –