I have an assignment to solve a Knapsack problem from a set of dataset i'm given and one of the ways i have to do solve it with is branch and bound depth first The program below works fine when given a dataset with a capacity of 100000 and number of items being 30 but when that increases to 341045 capacity and number of items being 50 the program gives me an error memory allocation failed not enough space I've tried dynamically allocating memory, program slows down to a crawl I've tried freeing up memory, i get errors I've tried to run the program with saving the selected items to only have a final value and free capacity, same issue not enough space for memory allocation so any help would be appreciated
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct {
int weight;
int value;
} Item;
typedef struct Node {
int value;
int weight;
int estimate;
int level;
int* selected; //pointer toy selected
} Node;
typedef struct QueueNode {
Node data;
struct QueueNode* next;
} QueueNode;
typedef struct {
QueueNode* front;
QueueNode* rear;
} Queue;
// Function to create a new queue
Queue* createQueue() {
Queue* queue = (Queue*)malloc(sizeof(Queue));
if (queue == NULL) {
perror("Memory allocation failed");
exit(EXIT_FAILURE);
}
queue->front = queue->rear = NULL;
return queue;
}
Node createNode(int value, int weight, int estimate, int level, int* selected, int length) {
Node newNode;
newNode.value = value;
newNode.weight = weight;
newNode.estimate = estimate;
newNode.level = level;
newNode.selected = (int*)malloc(length * sizeof(int)); // Allocate memory for the selected array
if (newNode.selected == NULL) {
perror("Memory allocation failed");
exit(EXIT_FAILURE);
}
for (int i = 0; i < length; i++) {
newNode.selected[i] = selected[i];
}
return newNode;
}
//Function to check if the queue is empty
int isEmpty(Queue* queue) {
return queue->front == NULL;
}
// Function to enqueue a node
void enqueue(Queue* queue, Node newNode) {
QueueNode* newNodePtr = (QueueNode*)malloc(sizeof(QueueNode));
if (newNodePtr == NULL) {
perror("Memory allocation failed");
exit(EXIT_FAILURE);
}
newNodePtr->data = newNode;
newNodePtr->next = NULL;
if (queue->rear == NULL) {
queue->front = queue->rear = newNodePtr;
return;
}
queue->rear->next = newNodePtr;
queue->rear = newNodePtr;
}
// Function to dequeue a node
Node dequeue(Queue* queue) {
if (isEmpty(queue)) {
perror("Queue is empty");
exit(EXIT_FAILURE);
}
QueueNode* temp = queue->front;
Node data = temp->data;
queue->front = queue->front->next;
if (queue->front == NULL)
queue->rear = NULL;
free(temp);
return data;
}
// Function to free the memory occupied by the queue
void freeQueue(Queue* queue) {
while (!isEmpty(queue)) {
dequeue(queue);
}
free(queue);
}
int main() {
FILE *file;
char filename[] = "pr2_50"; //ONOMA FILE
int K, N;
clock_t start, end;
double cpu_time_used;
start = clock();
// Open file
file = fopen(filename, "r");
if (file == NULL) {
perror("Error opening file");
return 1;
}
fscanf(file, "%d %d", &K, &N); //K=Knapsack Capacity, N=Number of items
// Allocate memory for items
Item *items = (Item *)malloc(N * sizeof(Item));
if (items == NULL) {
perror("Memory allocation failed");
fclose(file);
return 1;
}
int optimistic_value=0;
// Read items from file
for (int i = 0; i < N; i++) {
if (fscanf(file, "%d %d", &items[i].weight, &items[i].value) != 2) {
perror("Error reading file");
fclose(file);
return 1;
}
optimistic_value=optimistic_value+items[i].value;
}
fclose(file);
int level=0;
int max = 0;
int maxw=0;
Queue* queue = createQueue();
int current_value=0;
int current_weight=0;
int selection[N];
int finalselection[N];
for (int i=0;i<N;i++) {
selection[i] = 0;
finalselection[i] = 0;
}
Node newNode = createNode(current_value, current_weight, optimistic_value, level, selection, N);
enqueue(queue, newNode);
while(!isEmpty(queue))
{
Node currentNode = dequeue(queue);
level = currentNode.level+1;
if (level<=N){
current_weight = currentNode.weight;
current_value = currentNode.value;
optimistic_value = currentNode.estimate;
int *selection = (int *)malloc(N * sizeof(int));
if (selection == NULL) {
perror("Memory allocation failed");
exit(EXIT_FAILURE);
}
for (int i = 0; i < level - 1; i++) {
selection[i] = currentNode.selected[i];
}
if(current_weight+items[level-1].weight<=K && optimistic_value>max)
{
selection[level-1]=1;
Node additem = createNode(current_value+items[level-1].value, current_weight+items[level-1].weight, optimistic_value, level, selection, N);
enqueue(queue, additem);
if (max<additem.value){
max=additem.value;
maxw=additem.weight;
for (int i=0;i<N;i++) {
finalselection[i]=selection[i];
}
}
}
if(optimistic_value>max)
{
selection[level-1]=0;
Node noitem = createNode(current_value, current_weight, optimistic_value-items[level-1].value, level, selection, N);
enqueue(queue, noitem);
}
free(selection);
}
else{
freeQueue(queue);
K=K-maxw;
printf("Selected items:\n");
for (int i = 0; i < N; i++) {
if (finalselection[i]==1) {
printf("Item %d: Weight = %d, Value = %d\n", i+1, items[i].weight, items[i].value);
}
}
free(items);
break;
}
free(currentNode.selected);
}
printf("Total value in knapsack is %d \n ", max);
printf("Backpack capacity: %d\n", K);
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC * 1000; // Convert to milliseconds
printf("Program executed in %.2f milliseconds.\n", cpu_time_used);
return 0;
}
Valgrind Report:
==4874== Memcheck, a memory error detector
==4874== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4874== Using Valgrind-3.18.1-42b08ed5bd-20211015 and LibVEX; rerun with -h for copyright info
==4874== Command: ./a.out
==4874== Parent PID: 3343
==4874==
--4874--
--4874-- Valgrind options:
--4874-- --leak-check=full
--4874-- --show-leak-kinds=all
--4874-- --track-origins=yes
--4874-- --verbose
--4874-- --log-file=valgrind-out.txt
--4874-- Contents of /proc/version:
--4874-- Linux version 4.4.0-19041-Microsoft ([email protected]) (gcc version 5.4.0 (GCC) ) #3996-Microsoft Thu Jan 18 16:36:00 PST 2024
--4874--
--4874-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-lzcnt-rdtscp-sse3-ssse3-avx-avx2-bmi-f16c-rdrand-rdseed
--4874-- Page sizes: currently 4096, max supported 4096
--4874-- Valgrind library directory: /usr/libexec/valgrind
--4874-- Reading syms from /home/stratos/a.out
--4874-- Reading syms from /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
--4874-- Considering /usr/lib/debug/.build-id/15/921ea631d9f36502d20459c43e5c85b7d6ab76.debug ..
--4874-- .. build-id is valid
--4874-- Reading syms from /usr/libexec/valgrind/memcheck-amd64-linux
--4874-- object doesn't have a symbol table
--4874-- object doesn't have a dynamic symbol table
--4874-- Scheduler: using generic scheduler lock implementation.
--4874-- Reading suppressions file: /usr/libexec/valgrind/default.supp
==4874== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-4874-by-stratos-on-???
==4874== embedded gdbserver: writing to /tmp/vgdb-pipe-to-vgdb-from-4874-by-stratos-on-???
==4874== embedded gdbserver: shared mem /tmp/vgdb-pipe-shared-mem-vgdb-4874-by-stratos-on-???
==4874==
==4874== TO CONTROL THIS PROCESS USING vgdb (which you probably
==4874== don't want to do, unless you know exactly what you're doing,
==4874== or are doing some strange experiment):
==4874== /usr/bin/vgdb --pid=4874 ...command...
==4874==
==4874== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==4874== /path/to/gdb ./a.out
==4874== and then give GDB the following command
==4874== target remote | /usr/bin/vgdb --pid=4874
==4874== --pid is optional if only one valgrind process is running
==4874==
==4874== error calling PR_SET_PTRACER, vgdb might block
--4874-- REDIR: 0x402aa40 (ld-linux-x86-64.so.2:strlen) redirected to 0x580bcec2 (???)
--4874-- REDIR: 0x402a810 (ld-linux-x86-64.so.2:index) redirected to 0x580bcedc (???)
--4874-- Reading syms from /usr/libexec/valgrind/vgpreload_core-amd64-linux.so
--4874-- object doesn't have a symbol table
--4874-- Reading syms from /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so
--4874-- object doesn't have a symbol table
==4874== WARNING: new redirection conflicts with existing -- ignoring it
--4874-- old: 0x0402aa40 (strlen ) R-> (0000.0) 0x580bcec2 ???
--4874-- new: 0x0402aa40 (strlen ) R-> (2007.0) 0x0484ee30 strlen
--4874-- REDIR: 0x4027220 (ld-linux-x86-64.so.2:strcmp) redirected to 0x484fcd0 (strcmp)
--4874-- REDIR: 0x402afa0 (ld-linux-x86-64.so.2:mempcpy) redirected to 0x4853840 (mempcpy)
--4874-- Reading syms from /usr/lib/x86_64-linux-gnu/libc.so.6
--4874-- Considering /usr/lib/debug/.build-id/c2/89da5071a3399de893d2af81d6a30c62646e1e.debug ..
--4874-- .. build-id is valid
==4874== WARNING: new redirection conflicts with existing -- ignoring it
--4874-- old: 0x0490dc60 (memalign ) R-> (1011.0) 0x0484e080 memalign
--4874-- new: 0x0490dc60 (memalign ) R-> (1017.0) 0x0484e050 aligned_alloc
==4874== WARNING: new redirection conflicts with existing -- ignoring it
--4874-- old: 0x0490dc60 (memalign ) R-> (1011.0) 0x0484e080 memalign
--4874-- new: 0x0490dc60 (memalign ) R-> (1017.0) 0x0484e020 aligned_alloc
==4874== WARNING: new redirection conflicts with existing -- ignoring it
--4874-- old: 0x0490dc60 (memalign ) R-> (1011.0) 0x0484e080 memalign
--4874-- new: 0x0490dc60 (memalign ) R-> (1017.0) 0x0484e050 aligned_alloc
==4874== WARNING: new redirection conflicts with existing -- ignoring it
--4874-- old: 0x0490dc60 (memalign ) R-> (1011.0) 0x0484e080 memalign
--4874-- new: 0x0490dc60 (memalign ) R-> (1017.0) 0x0484e020 aligned_alloc
--4874-- REDIR: 0x4910720 (libc.so.6:strnlen) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x49109e0 (libc.so.6:strpbrk) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x49102e0 (libc.so.6:strcmp) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x492ecd0 (libc.so.6:wcsnlen) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x49116d0 (libc.so.6:memset) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x492d540 (libc.so.6:wcslen) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4911c10 (libc.so.6:memcpy@@GLIBC_2.14) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x492d370 (libc.so.6:wcschr) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4910260 (libc.so.6:index) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4910960 (libc.so.6:rindex) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x49115a0 (libc.so.6:memmove) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
==4874== Preferring higher priority redirection:
--4874-- old: 0x04a087c0 (__memcpy_avx_unalign) R-> (2018.0) 0x04850f90 __memcpy_avx_unaligned_erms
--4874-- new: 0x04a087c0 (__memcpy_avx_unalign) R-> (2018.1) 0x04852880 memmove
--4874-- REDIR: 0x492d3f0 (libc.so.6:wcscmp) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x49119e0 (libc.so.6:stpncpy) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x492d9b0 (libc.so.6:wmemchr) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4910830 (libc.so.6:strncmp) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4911a70 (libc.so.6:strcasecmp) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4910420 (libc.so.6:strcspn) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x492d470 (libc.so.6:wcscpy) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x49101d0 (libc.so.6:strcat) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4911b60 (libc.so.6:strncasecmp_l) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4911480 (libc.so.6:bcmp) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4919570 (libc.so.6:memrchr) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4913010 (libc.so.6:strchrnul) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4910390 (libc.so.6:strcpy) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4911b10 (libc.so.6:strcasecmp_l) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x49106a0 (libc.so.6:strlen) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x49108d0 (libc.so.6:strncpy) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4911950 (libc.so.6:stpcpy) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x49113f0 (libc.so.6:memchr) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4910b00 (libc.so.6:strspn) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x49117d0 (libc.so.6:mempcpy) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4911ac0 (libc.so.6:strncasecmp) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4912f80 (libc.so.6:rawmemchr) redirected to 0x483f220 (_vgnU_ifunc_wrapper)
--4874-- REDIR: 0x4a05610 (libc.so.6:__strrchr_avx2) redirected to 0x484e810 (rindex)
--4874-- REDIR: 0x490d0a0 (libc.so.6:malloc) redirected to 0x4848820 (malloc)
--4874-- REDIR: 0x4910fc0 (libc.so.6:__GI_strstr) redirected to 0x4853ae0 (__strstr_sse2)
--4874-- REDIR: 0x490d3e0 (libc.so.6:free) redirected to 0x484b210 (free)
--4874-- REDIR: 0x4a057e0 (libc.so.6:__strlen_avx2) redirected to 0x484ed10 (strlen)
--4874-- REDIR: 0x4a05400 (libc.so.6:__strchrnul_avx2) redirected to 0x4853330 (strchrnul)
--4874-- REDIR: 0x4a08780 (libc.so.6:__mempcpy_avx_unaligned_erms) redirected to 0x4853440 (mempcpy)
==4874== Conditional jump or move depends on uninitialised value(s)
==4874== at 0x109D76: main (asd.c:195)
==4874== Uninitialised value was created by a heap allocation
==4874== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4874== by 0x109A72: main (asd.c:160)
==4874==
--4874-- REDIR: 0x4a087c0 (libc.so.6:__memcpy_avx_unaligned_erms) redirected to 0x4852880 (memmove)
==4874==
==4874== HEAP SUMMARY:
==4874== in use at exit: 1,562,760 bytes in 13,023 blocks
==4874== total heap usage: 158,459 allocs, 145,436 frees, 13,990,336 bytes allocated
==4874==
==4874== Searching for pointers to 13,023 not-freed blocks
==4874== Checked 107,456 bytes
==4874==
==4874== 1,562,760 bytes in 13,023 blocks are definitely lost in loss record 1 of 1
==4874== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4874== by 0x10932D: createNode (asd.c:43)
==4874== by 0x109CEB: main (asd.c:185)
==4874==
==4874== LEAK SUMMARY:
==4874== definitely lost: 1,562,760 bytes in 13,023 blocks
==4874== indirectly lost: 0 bytes in 0 blocks
==4874== possibly lost: 0 bytes in 0 blocks
==4874== still reachable: 0 bytes in 0 blocks
==4874== suppressed: 0 bytes in 0 blocks
==4874==
==4874== ERROR SUMMARY: 10 errors from 2 contexts (suppressed: 0 from 0)
==4874==
==4874== 9 errors in context 1 of 2:
==4874== Conditional jump or move depends on uninitialised value(s)
==4874== at 0x109D76: main (asd.c:195)
==4874== Uninitialised value was created by a heap allocation
==4874== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==4874== by 0x109A72: main (asd.c:160)
==4874==
==4874== ERROR SUMMARY: 10 errors from 2 contexts (suppressed: 0 from 0)