On the verse of memory leaks

This commit is contained in:
Ano-sys
2025-02-01 11:27:20 +01:00
parent 4910b0db61
commit 7f6d6c1479
3 changed files with 88 additions and 29 deletions
+1
View File
@@ -29,6 +29,7 @@ char *key_value_pair_list_to_string(key_value_pair **head){
} }
if(!ret){ if(!ret){
ret = strdup(kvp2str); ret = strdup(kvp2str);
free(kvp2str);
kvp_it = kvp_it->next; kvp_it = kvp_it->next;
} }
else{ else{
+71 -23
View File
@@ -13,12 +13,15 @@ typedef struct{
int port; int port;
char *data; char *data;
TYPE type; TYPE type;
void *context;
}THREAD_ARGS; }THREAD_ARGS;
pthread_mutex_t words_mutex; pthread_mutex_t words_mutex;
char *words_list; char *words_list;
char *sanitize_input(char *input);
char *get_file_content(FILE *fp) char *get_file_content(FILE *fp)
{ {
if (!fp) { if (!fp) {
@@ -84,7 +87,19 @@ char *get_file_content(FILE *fp)
void *receiverFunc(void *args) void *receiverFunc(void *args)
{ {
THREAD_ARGS *params = (THREAD_ARGS*)args; THREAD_ARGS *params = (THREAD_ARGS*)args;
void *context = zmq_ctx_new(); if(!params){
perror("[THREAD] invalid arguments");
return NULL;
}
if (params->port <= 0) {
fprintf(stderr, "[THREAD] Invalid port: %d\n", params->port);
free(params);
return NULL;
}
void *context = params->context;
if(!context){ if(!context){
perror("[THREAD] Failed to create context"); perror("[THREAD] Failed to create context");
free(params); free(params);
@@ -99,7 +114,7 @@ void *receiverFunc(void *args)
} }
char addr[22]; char addr[22];
snprintf(addr, 21, "tcp://localhost:%d", params->port); snprintf(addr, 21, "tcp://localhost:%d", params->port); // BUG: FIX PORT 0
int rc = zmq_connect(requester, addr); int rc = zmq_connect(requester, addr);
if (rc != 0){ if (rc != 0){
@@ -111,33 +126,52 @@ void *receiverFunc(void *args)
} }
fprintf(stderr, "[THREAD] Connected to worker: %s\n", addr); fprintf(stderr, "[THREAD] Connected to worker: %s\n", addr);
size_t len = strlen(params->data) + 4; char *data = sanitize_input(params->data);
if(!data){
perror("[THREAD] Failed to sanitize input");
free(params->data);
free(params);
zmq_close(requester);
zmq_ctx_destroy(context);
return NULL;
}
free(params->data);
size_t len = strlen(data) + 4;
char *request = (char*)malloc(sizeof(char) * len); char *request = (char*)malloc(sizeof(char) * len);
if(!request){ if(!request){
perror("[THREAD] Failed to allocate memory for request"); perror("[THREAD] Failed to allocate memory for request");
free(params); free(params);
free(data);
zmq_close(requester); zmq_close(requester);
zmq_ctx_destroy(context); zmq_ctx_destroy(context);
return NULL; } return NULL;
}
switch(params->type){ switch(params->type){
case MAP: case MAP:
snprintf(request, len, "map%s", params->data); snprintf(request, len, "map%s", data);
break; break;
case RED: case RED:
snprintf(request, len, "red%s", params->data); snprintf(request, len, "red%s", data);
break; break;
case RIP: case RIP:
snprintf(request, len, "rip"); snprintf(request, len, "rip");
break; break;
default: default:
perror("[THREAD] Got unsupported request"); perror("[THREAD] Got unsupported request");
free(data);
free(params); free(params);
free(request); free(request);
zmq_close(requester); zmq_close(requester);
zmq_ctx_destroy(context); zmq_ctx_destroy(context);
return NULL; return NULL;
} }
free(data);
fprintf(stderr, "[THREAD] Send request: %s\n", request); fprintf(stderr, "[THREAD] Send request: %s\n", request);
if(zmq_send(requester, request, strlen(request), 0) == -1){ if(zmq_send(requester, request, strlen(request), 0) == -1){
perror("[THREAD] Failed to send request"); perror("[THREAD] Failed to send request");
@@ -151,8 +185,8 @@ void *receiverFunc(void *args)
free(request); free(request);
fprintf(stderr, "[THREAD]: Waiting for response\n"); fprintf(stderr, "[THREAD]: Waiting for response\n");
char reply[MESSAGE_LENGTH]; char reply[MESSAGE_LENGTH + 1];
int bytes_recv = zmq_recv(requester, reply, MESSAGE_LENGTH - 1, 0); int bytes_recv = zmq_recv(requester, reply, MESSAGE_LENGTH, 0);
if (bytes_recv == -1){ if (bytes_recv == -1){
perror("[THREAD] Failed to receive reply"); perror("[THREAD] Failed to receive reply");
free(params); free(params);
@@ -205,12 +239,15 @@ void *receiverFunc(void *args)
pthread_mutex_unlock(&words_mutex); pthread_mutex_unlock(&words_mutex);
zmq_close(requester); zmq_close(requester);
zmq_ctx_destroy(context);
return NULL; return NULL;
} }
char *sanitize_input(char *input){ char *sanitize_input(char *input){
if(!input) return NULL;
int i = 0;
char *ret = malloc(sizeof(char)); char *ret = malloc(sizeof(char));
if(!ret){ if(!ret){
perror("[MAIN - sanitize_input] Failed to allocate memory for ret"); perror("[MAIN - sanitize_input] Failed to allocate memory for ret");
@@ -221,21 +258,20 @@ char *sanitize_input(char *input){
char *it = input; char *it = input;
while(!isalpha(*it)) it++; while(!isalpha(*it)) it++;
int i = 0;
bool writeSpace = false; bool writeSpace = false;
while(*it){ while(*it){
if(isalpha(*it)){ if(isalpha(*it)){
char *tmp = NULL; char *tmp = NULL;
if(writeSpace){ if(writeSpace){
tmp = realloc(ret, strlen(ret) + 2); tmp = realloc(ret, i + 3);
} }
else{ else{
tmp = realloc(ret, strlen(ret) + 1); tmp = realloc(ret, i + 2);
} }
if(!tmp){ if(!tmp){
perror("[MAIN - sanitize_input] Failed to realloc memory for ret"); perror("[MAIN - sanitize_input] Failed to realloc memory for ret");
free(ret); free(ret);
exit(1); return NULL;
} }
ret = tmp; ret = tmp;
if(writeSpace) ret[i++] = ' '; if(writeSpace) ret[i++] = ' ';
@@ -247,11 +283,11 @@ char *sanitize_input(char *input){
writeSpace = true; writeSpace = true;
} }
} }
ret[strlen(ret) + 1] = '\0'; ret[i] = '\0';
return ret; return ret;
} }
void map(size_t worker_count, char **worker_ports, const char *filename) { void map(size_t worker_count, char **worker_ports, const char *filename, void *context) {
FILE *fp = fopen(filename, "rb"); FILE *fp = fopen(filename, "rb");
char *raw = get_file_content(fp); char *raw = get_file_content(fp);
if(!raw){ if(!raw){
@@ -281,13 +317,13 @@ void map(size_t worker_count, char **worker_ports, const char *filename) {
size_t offset = 0; size_t offset = 0;
while (offset < total_len) { while (offset < total_len) {
size_t chunk_size = (total_len - offset >= MESSAGE_LENGTH) ? MESSAGE_LENGTH : (total_len - offset); size_t chunk_size = (total_len - offset >= PAYLOAD_LENGTH + 1) ? PAYLOAD_LENGTH + 1 : (total_len - offset);
if (offset + chunk_size < total_len) { if (offset + chunk_size < total_len) {
size_t new_chunk_size = chunk_size; size_t new_chunk_size = chunk_size;
while (new_chunk_size > 0) { while (new_chunk_size > 0) {
char c = content[offset + new_chunk_size]; char c = content[offset + new_chunk_size];
if (!isalpha((unsigned char)c)) { if (!isalpha((unsigned char)c) || (offset + chunk_size < strlen(content) && (content[offset + chunk_size] == ' ' || content[offset + chunk_size] == '\0'))) {
break; break;
} }
new_chunk_size--; new_chunk_size--;
@@ -324,6 +360,7 @@ void map(size_t worker_count, char **worker_ports, const char *filename) {
args->type = MAP; args->type = MAP;
args->data = strndup(content + offset, chunk_size); args->data = strndup(content + offset, chunk_size);
args->context = context;
if (pthread_create(&threads[thread_count], NULL, receiverFunc, (void*)args) != 0) { if (pthread_create(&threads[thread_count], NULL, receiverFunc, (void*)args) != 0) {
perror("[MAIN - map] Failed to create thread"); perror("[MAIN - map] Failed to create thread");
@@ -336,13 +373,13 @@ void map(size_t worker_count, char **worker_ports, const char *filename) {
worker_index = (worker_index + 1) % worker_count; worker_index = (worker_index + 1) % worker_count;
thread_count++; thread_count++;
} }
free(content);
for (size_t i = 0; i < thread_count; i++) { for (size_t i = 0; i < thread_count; i++) {
pthread_join(threads[i], NULL); pthread_join(threads[i], NULL);
} }
free(threads); free(threads);
free(content);
} }
char *extract_reduce_string(const char * toExtract){ char *extract_reduce_string(const char * toExtract){
@@ -363,7 +400,7 @@ char *extract_reduce_string(const char * toExtract){
return extracted; return extracted;
} }
void reduce(char *toReduce, size_t worker_count, char **worker_ports) { void reduce(const char *toReduce, size_t worker_count, char **worker_ports, void *context) {
if (!toReduce || worker_count == 0) { if (!toReduce || worker_count == 0) {
fprintf(stderr, "[MAIN - reduce] Invalid input parameters.\n"); fprintf(stderr, "[MAIN - reduce] Invalid input parameters.\n");
return; return;
@@ -389,6 +426,7 @@ void reduce(char *toReduce, size_t worker_count, char **worker_ports) {
while (new_size > 0) { while (new_size > 0) {
char c = toReduce[offset + new_size]; char c = toReduce[offset + new_size];
if (isdigit((unsigned char)c)) { if (isdigit((unsigned char)c)) {
new_size++;
break; break;
} }
new_size--; new_size--;
@@ -410,6 +448,7 @@ void reduce(char *toReduce, size_t worker_count, char **worker_ports) {
args->port = atol(worker_ports[worker_index]); args->port = atol(worker_ports[worker_index]);
args->data = strndup(toReduce + offset, chunk_size); args->data = strndup(toReduce + offset, chunk_size);
args->type = RED; args->type = RED;
args->context = context;
if (!args->data) { if (!args->data) {
perror("[MAIN - reduce] Failed to allocate memory for chunk data"); perror("[MAIN - reduce] Failed to allocate memory for chunk data");
@@ -437,7 +476,7 @@ void reduce(char *toReduce, size_t worker_count, char **worker_ports) {
} }
void rip(size_t worker_count, char **worker_ports){ void rip(size_t worker_count, char **worker_ports, void *context){
pthread_t *threads = malloc(sizeof(pthread_t) * worker_count); pthread_t *threads = malloc(sizeof(pthread_t) * worker_count);
if(!threads){ if(!threads){
perror("[MAIN- reduce] Failed to allocate memory for threads"); perror("[MAIN- reduce] Failed to allocate memory for threads");
@@ -458,6 +497,7 @@ void rip(size_t worker_count, char **worker_ports){
args->port = atol(worker_ports[i]); args->port = atol(worker_ports[i]);
args->data = strdup("rip"); args->data = strdup("rip");
args->type = RIP; args->type = RIP;
args->context = context;
if (!args->data) { if (!args->data) {
fprintf(stderr, "[MAIN - reduce] Warning: extract_reduce_string() returned NULL\n"); fprintf(stderr, "[MAIN - reduce] Warning: extract_reduce_string() returned NULL\n");
@@ -540,8 +580,14 @@ int main(const int argc, char **argv) {
pthread_mutex_init(&words_mutex, NULL); pthread_mutex_init(&words_mutex, NULL);
void *context = zmq_ctx_new();
if(!context){
perror("[MAIN] zmq_ctx_new failed");
exit(1);
}
// MAP // MAP
map(argc - 2, argv + 2, argv[1]); map(argc - 2, argv + 2, argv[1], context);
fprintf(stderr, "MAP:\n%s\n", words_list); fprintf(stderr, "MAP:\n%s\n", words_list);
char *word_list_mapped = strdup(words_list); char *word_list_mapped = strdup(words_list);
@@ -549,7 +595,7 @@ int main(const int argc, char **argv) {
words_list = NULL; words_list = NULL;
// REDUCE // REDUCE
reduce(word_list_mapped, argc - 2, argv + 2); reduce(word_list_mapped, argc - 2, argv + 2, context);
free(word_list_mapped); free(word_list_mapped);
char *word_list_reduced = strdup(words_list); char *word_list_reduced = strdup(words_list);
@@ -559,12 +605,14 @@ int main(const int argc, char **argv) {
fprintf(stderr, "REDUCE:\n%s\n", word_list_reduced); fprintf(stderr, "REDUCE:\n%s\n", word_list_reduced);
// RIP // RIP
rip(argc - 2, argv + 2); rip(argc - 2, argv + 2, context);
// print words_list // print words_list
print_words_list(word_list_reduced); print_words_list(word_list_reduced);
free(word_list_reduced); free(word_list_reduced);
pthread_mutex_destroy(&words_mutex); pthread_mutex_destroy(&words_mutex);
zmq_ctx_destroy(context);
return 0; return 0;
} }
+16 -6
View File
@@ -31,8 +31,9 @@ int main(int argc, char **argv){
while(thread_count < worker_count){ while(thread_count < worker_count){
int *port = malloc(sizeof(int)); int *port = malloc(sizeof(int));
*port = atoi(argv[worker_index]); *port = atoi(argv[worker_index]);
if(pthread_create(&threads[thread_count++], NULL, workerFunc, port) != 0){ if(pthread_create(&threads[thread_count++], NULL, workerFunc, (void*)port) != 0){
perror("[MAIN] Failed to create thread"); perror("[MAIN] Failed to create thread");
free(port);
free(threads); free(threads);
exit(1); exit(1);
} }
@@ -65,8 +66,13 @@ TYPE get_request_type(const char *request){
} }
void* workerFunc(void *args){ void* workerFunc(void *args){
if(!args){
perror("[THREAD] Invalid arguments");
return NULL;
}
int port = *(int*)args; int port = *(int*)args;
free(args); free(args);
void *context = zmq_ctx_new(); void *context = zmq_ctx_new();
if(!context){ if(!context){
perror("[THREAD] Failed to create context"); perror("[THREAD] Failed to create context");
@@ -94,10 +100,10 @@ void* workerFunc(void *args){
key_value_pair *head = NULL; key_value_pair *head = NULL;
key_value_pair *tail = NULL; key_value_pair *tail = NULL;
char request[MESSAGE_LENGTH + 1]; char request[MESSAGE_LENGTH + 1] = {0};
int bytes_recv = zmq_recv(responder, request, MESSAGE_LENGTH, 0); int bytes_recv = zmq_recv(responder, request, MESSAGE_LENGTH, 0);
if(bytes_recv <= 0){ if(bytes_recv < 3){ // minimal receive is TYPE
perror("Failed to receive request"); perror("Failed to receive valid request");
continue; continue;
} }
@@ -106,9 +112,11 @@ void* workerFunc(void *args){
char endpoint[256]; char endpoint[256];
size_t endpoint_size = sizeof(endpoint); size_t endpoint_size = sizeof(endpoint);
if (zmq_getsockopt(responder, ZMQ_LAST_ENDPOINT, endpoint, &endpoint_size) == 0) { if (zmq_getsockopt(responder, ZMQ_LAST_ENDPOINT, endpoint, &endpoint_size) == 0) {
fprintf(stderr, "Got request from: %s\n", endpoint); fprintf(stderr, "Got request on: %s\n", endpoint);
} }
fprintf(stderr, "Received: %s\n", request);
const TYPE type = get_request_type(request); const TYPE type = get_request_type(request);
char *content = request + TYPE_LENGTH; char *content = request + TYPE_LENGTH;
@@ -137,6 +145,7 @@ void* workerFunc(void *args){
exit(1); exit(1);
break; break;
} }
fprintf(stderr, "Sending content: %s\n", ret); fprintf(stderr, "Sending content: %s\n", ret);
if(zmq_send(responder, ret, strlen(ret), 0) < 0){ if(zmq_send(responder, ret, strlen(ret), 0) < 0){
perror("Failed to send response"); perror("Failed to send response");
@@ -178,7 +187,7 @@ char* get_word(const char *request){
return NULL; return NULL;
while(*request && isalpha(*request)){ while(*request && isalpha(*request)){
char *new_word = (char*)realloc(word, strlen(word) + 2); // realloc word size + \0 and extra char space char *new_word = (char*)realloc(word, length + 2); // realloc word size + \0 and extra char space
if(!new_word){ if(!new_word){
free(word); free(word);
return NULL; return NULL;
@@ -193,6 +202,7 @@ char* get_word(const char *request){
} }
char* map(const char *content, key_value_pair **head, key_value_pair **tail){ char* map(const char *content, key_value_pair **head, key_value_pair **tail){
if(!content) return NULL;
char *content_iterator = (char*)content; char *content_iterator = (char*)content;
void *content_start_address = (void*)content; void *content_start_address = (void*)content;
size_t content_length = strlen(content); size_t content_length = strlen(content);