I'm implementing the Data Encryption Standard in C for a personal learning project and I have a seg fault that has been driving me up the wall for the past 3 days. I understand this isn't the place for "fix my code for me" type questions, but I need a second pair of eyes to look over this:
/*we must define our own modulo, as the C modulo returns unexpected results:*/
#define MOD(x, n) ((x % n + n) % n)
/*example: the 12th bit should be in the second byte so return 1 (the first byte being 0)*/
#define GET_BYTE_NUM(bit_index) (bit_index/8)
/*example: a bit index of 12 means this bit is the 4th bit of the second byte so return 4*/
#define GET_BIT_NUM(bit_index) MOD(bit_index, 8)
typedef unsigned char byte;
/*each row represents a byte, at the bit to be place in the position
* for example for the first row (first byte) we will place bits 31, 0, 1, 2, 3, 4 in
* in bit positions 0-6, respectively. The last two bits will be left blank. Since this is supposed to be a crypto implementation, static prevents this value from being accessed outside the file.*/
const static byte e_box[8][6] = { {31, 0, 1, 2, 3, 4}, {3, 4, 5, 6, 7, 8}, {7, 8, 9, 10, 11, 12}, {11, 12, 13, 14, 15, 16}, {12, 16, 17, 18, 19, 20}, {19, 20, 21, 22, 23, 24},
{23, 24, 25, 26, 27, 28}, {27, 28, 29, 30, 31, 0} }
void e(byte **four_byte_block)
{
int i, n, l = 0, four_bit_num, four_byte_num;
/*create the new byte_block and initialize all values to 0, we will have 4 spaces of bytes, so 32 bits in total*/
byte *new_byte_block = (byte*)calloc(4, sizeof(byte));
byte bit;
for(i = 0 i < 8; i++)
{
for(n = 0; n < 6; n++)
{
/*get the byte number of the bit at l*/
four_byte_num = GET_BYTE_NUM(e_box[i][n]);
/*find what index the bit at l is in its byte*/
half_bit_num = GET_BIT_NUM(e_box[i][n]);
bit = *four_byte_block[half_byte_num]; /*SEG FAULT!*/
}
}
/*finally, set four_byte_block equal to new_byte_block*/
/*four_byte_block = NULL;
* four_byte_block = new_byte_block;*/
}
I have narrowed the problem down to the line marked /SEG FAULT!/ but I can't see what the issue is. When I print the half_byte_num, I get a number that is within bounds of half_block, and when I print the values of half_block, I can confirm that those values exist.
I believe I may be doing something wrong with the pointers ie by passing **four_byte_block, (a pointer to a pointer) and it's manipulation could be causing the seg fault.
Have you tried this:
bit = (*four_byte_block)[half_byte_num];
Instead of this:
bit = *four_byte_block[half_byte_num];
Those are not the same, as an example, take the following code:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
char **lines = malloc(sizeof(char *) * 8);
for (int i = 0; i < 8l; i++)
lines[i] = strdup("hey");
printf("%c\n", *lines[1]);
printf("%c\n",(*lines)[1]);
return 0;
}
The former will output h.
The latter will output e.
This is because of the operators precedence, [] will be evalued before *, thus if you want to go to the nth index of *foo, you need to type (*foo)[n].
I searched all over the internet and watched tons of video and nobody does this thing :
Create a struct matrix that can dynamicly change its KxN direct from the main , for example
I will use java :
Matrix(int k , int n){
int Mat[k][n];
}
main(){
Matrix a = new Matrix (2,3);
a.Mat[0][0] = 1;
syso(a.Mat[0][0]);
}
Im begining to think its imposible , I tried to alocate memory from the main and it worked , this is how I did it
int** arr = malloc(sizeof(int*)*n)
for (int i = 0 ; i < k ; i=+){
arr[i] = malloc(sizeof(int)*3);
}
but the problem is I cannot do it inside a struct for some reason .. I need to keep my main clean so all my work should be done above the main ,
this is my C program that doesn't work :
//__________________HEADER_________________________________________________//
#include <stdio.h>
#include <stdlib.h>
//__________________________________________________________________________//
//__________________OBJECTS______________________________________________________//
typedef struct {
int n , k ;
int** Mat;
}Matrix;
//______________________________________________________________________________//
//___________________MAIN_____________________________________________________//
int main (void) {
printf("Start..\n\n");
Matrix aqq = {2,5} ;
aqq.Mat[0][0] = 5 ;
printf("\n size : %dx%d first element : %d \n",aqq.n , aqq.k , aqq.Mat[0][0]);
printf("\n\nEnd\n");
}
//______________________________________________________________________________//
I need to make all the getters and setter mult transpose all the matrices functions including linear copying guassian elemination .. everything and I would like to receive maybe a link to some guide lines or even a book , I don't care as long as I could study from it because its really difficult to work like that there are too many rules that involves memory and not a single reliable source of information because every body doing the easy stuff on the tutorials
so to sum up , the final goal is to control every function completely through the main
Here's code that could be split into three files — matrix.h, matrix.c and test.matrix.c.
The header matrix.h declares an opaque type Matrix and some functions to manipulate that type — a constructor (the third option in my comment), a destructor, routines to get and set element values, and routines to get the array dimensions.
The implementation file matrix.c defines the functions. It uses assertions to ensure the validity of arguments — lazy but effective as long as you never compile with -DNDEBUG. If you do suppress assertions, you need to put proper error handling into the functions. Deciding how to handle errors detected by corrupted data structures is a project-wide decision. The code is careful to free any already allocated memory if there is an allocation failure during the construction of a matrix. It defines the struct Matrix, but that type is not accessible outside this source file.
The test file test.matrix.c provides some code to use all the functions declared in matrix.h and demonstrates that square and rectangular matrices work. The code in this file cannot dereference the matrix structure; it must use the access functions.
The resulting code is quite big, but it does the job and demonstrates that you can indeed use structures to store matrices. Write a matrix multiplication routine is a simple exercise.
/* SOF - matrix.h */
#ifndef MATRIX_H_INCLUDED
#define MATRIX_H_INCLUDED
#include <stddef.h> /* size_t */
enum { MATRIX_MAX_SIZE = 1000 };
typedef struct Matrix Matrix; /* Opaque type */
extern Matrix *matrix_constructor(size_t rows, size_t cols);
extern void matrix_destructor(Matrix *mtx);
extern int matrix_get_element(const Matrix *mtx, size_t r, size_t c);
extern void matrix_set_element(Matrix *mtx, size_t r, size_t c, int v);
extern size_t matrix_get_cols(const Matrix *mtx);
extern size_t matrix_get_rows(const Matrix *mtx);
#endif /* MATRIX_H_INCLUDED */
/* EOF - matrix.h */
/* SOF - matrix.c */
/*#include "matrix.h"*/
#include <assert.h>
#include <stdlib.h>
struct Matrix
{
size_t rows;
size_t cols;
int **data;
};
/* It is important to prevent memory leaks on allocation failure */
Matrix *matrix_constructor(size_t rows, size_t cols)
{
assert(rows <= MATRIX_MAX_SIZE && rows > 0);
assert(cols <= MATRIX_MAX_SIZE && cols > 0);
Matrix *mtx = malloc(sizeof(*mtx));
if (mtx == NULL)
return NULL;
mtx->data = malloc(sizeof(*mtx->data) * rows);
if (mtx->data == NULL)
{
free(mtx);
return NULL;
}
for (size_t i = 0; i < rows; i++)
{
mtx->data[i] = malloc(sizeof(*mtx->data[i]) * cols);
if (mtx->data[i] == NULL)
{
while (i > 0)
free(mtx->data[--i]);
free(mtx);
return NULL;
}
}
mtx->rows = rows;
mtx->cols = cols;
return mtx;
}
void matrix_destructor(Matrix *mtx)
{
assert(mtx != NULL && mtx->data != NULL);
assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
for (size_t i = 0; i < mtx->rows; i++)
free(mtx->data[i]);
free(mtx->data);
free(mtx);
}
int matrix_get_element(const Matrix *mtx, size_t r, size_t c)
{
assert(mtx != NULL && mtx->data != NULL);
assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
return mtx->data[r][c];
}
void matrix_set_element(Matrix *mtx, size_t r, size_t c, int v)
{
assert(mtx != NULL && mtx->data != NULL);
assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
mtx->data[r][c] = v;
}
size_t matrix_get_rows(const Matrix *mtx)
{
assert(mtx != NULL && mtx->data != NULL);
assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
return mtx->rows;
}
size_t matrix_get_cols(const Matrix *mtx)
{
assert(mtx != NULL && mtx->data != NULL);
assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
return mtx->cols;
}
/* EOF - matrix.c */
/* SOF - test.matrix.c */
/*#include "matrix.h"*/
#include <errno.h>
#include <stdarg.h>
#include <stdint.h> /* intmax_t */
#include <stdio.h>
/*#include <stdlib.h>*/
#include <string.h>
#include <time.h>
/* Cannot dereference Matrix pointers here! */
static void matrix_print(const char *tag, const Matrix *mtx, int width)
{
size_t rows = matrix_get_rows(mtx);
size_t cols = matrix_get_cols(mtx);
printf("%s (%zux%zu):\n", tag, rows, cols);
for (size_t r = 0; r < rows; r++)
{
const char *pad = "";
for (size_t c = 0; c < cols; c++)
{
printf("%s%*d", pad, width, matrix_get_element(mtx, r, c));
pad = ", ";
}
putchar('\n');
}
}
static void matrix_random(Matrix *mtx)
{
size_t rows = matrix_get_rows(mtx);
size_t cols = matrix_get_cols(mtx);
for (size_t r = 0; r < rows; r++)
{
for (size_t c = 0; c < cols; c++)
matrix_set_element(mtx, r, c, (rand() % (rows * cols) + 1));
}
}
static int i_log10(size_t n)
{
if (n < 10)
return 1;
int c = 1;
while (n >= 10)
{
n /= 10;
c++;
}
return c;
}
static int i_pow10(int n)
{
int r = 1;
while (n-- > 0)
r *= 10;
return r;
}
static void matrix_ordered(Matrix *mtx)
{
size_t rows = matrix_get_rows(mtx);
size_t cols = matrix_get_cols(mtx);
int mul = i_pow10(i_log10(cols));
for (size_t r = 0; r < rows; r++)
{
for (size_t c = 0; c < cols; c++)
matrix_set_element(mtx, r, c, (r + 1) * mul + c + 1);
}
}
static void err_exit(const char *fmt, ...)
{
va_list args;
int errnum = errno;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
if (errnum != 0)
fprintf(stderr, " (%d: %s)", errnum, strerror(errnum));
putc('\n', stderr);
exit(EXIT_FAILURE);
}
static Matrix *matrix_checked_constructor(const char *tag, size_t rows, size_t cols)
{
Matrix *mp = matrix_constructor(rows, cols);
if (mp == NULL)
err_exit("Failed to construct matrix %s", tag);
return mp;
}
int main(void)
{
Matrix *mi5 = matrix_checked_constructor("MI5", 5, 5);
Matrix *mi6 = matrix_checked_constructor("MI6", 6, 6);
Matrix *ks69 = matrix_checked_constructor("KS69", 6, 9);
Matrix *bw1815 = matrix_checked_constructor("BW1815", 18, 15);
time_t now = time(0);
srand(now);
printf("Seed: %jd\n", (intmax_t)now);
matrix_random(mi5);
matrix_random(mi6);
matrix_ordered(ks69);
matrix_ordered(bw1815);
matrix_print("MI5", mi5, 2);
matrix_print("MI6", mi6, 2);
matrix_print("KS69", ks69, 3);
matrix_print("BW1815", bw1815, 4);
matrix_destructor(mi5);
matrix_destructor(mi6);
return 0;
}
/* EOF - test.matrix.c */
Example output:
Seed: 1605897737
MI5 (5x5):
14, 22, 5, 21, 11
23, 5, 23, 7, 2
10, 9, 9, 2, 24
10, 6, 21, 6, 11
5, 11, 5, 18, 3
MI6 (6x6):
25, 33, 4, 18, 24, 19
6, 1, 23, 19, 6, 24
17, 2, 26, 3, 2, 32
7, 34, 8, 5, 11, 33
6, 7, 34, 13, 21, 14
15, 25, 32, 11, 28, 28
KS69 (6x9):
11, 12, 13, 14, 15, 16, 17, 18, 19
21, 22, 23, 24, 25, 26, 27, 28, 29
31, 32, 33, 34, 35, 36, 37, 38, 39
41, 42, 43, 44, 45, 46, 47, 48, 49
51, 52, 53, 54, 55, 56, 57, 58, 59
61, 62, 63, 64, 65, 66, 67, 68, 69
BW1815 (18x15):
101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115
201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215
301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315
401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415
501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515
601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615
701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715
801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815
901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915
1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015
1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115
1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215
1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315
1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415
1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515
1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615
1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715
1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815
I need to solve the knapsack problem recursively, memoized and with dynamic programming. Currently I'm stuck at the dynamic programming method.
I adapted the code from what I found elsewhere on the internet. Currently the output is not correct.
The problem involves profit and mass. Each item has a profit and mass associated, there is a MAX_N (umber) of items available and a MAX_CAPACITY for mass. The aim is to have as much "profit" in the knapsack as possible.
Here is an example provided by the exercise:
Example: Given a knapsack of capacity 5, and items with mass[] = {2, 4, 3, 2}
and profit profit[] = {45, 40, 25, 15}, the best combination would be item 0 (with mass 2 and profit 45) and item 2 (with mass 3 and with profit 25) for a total profit of 70. No other combination with mass 5 or less has a greater profit.
Here is the complete code:
#include <stdio.h>
#include <stdlib.h>
#define MAX_N 10
#define MAX_CAPACITY 165
int m[MAX_N][MAX_CAPACITY];
int max(int x, int y) {
return x ^ ((x ^ y) & -(x < y));
}
int min(int x, int y) {
return y ^ ((x ^ y) & -(x < y));
}
int knapsackRecursive(int capacity, int mass[], int profit[], int n) {
if (n < 0)
return 0;
if (mass[n] > capacity)
return knapsackRecursive(capacity, mass, profit, n-1);
else
return max(knapsackRecursive(capacity, mass, profit, n-1), knapsackRecursive(capacity - mass[n], mass, profit, n-1) + profit[n]);
}
int knapsackMemoized(int capacity, int mass[], int profit[], int n) {
}
int knapsackDynamic(int capacity, int mass[], int profit[], int n) {
int i;
int j;
for (i = 0; i <= n; i++) {
for (j = 0; j <= capacity; j++) {
if (i == 0 || j == 0)
m[i][j] = 0;
else if (mass[i-1] <= j)
m[i][j] = max(profit[i-1] + m[i-1][j-mass[i-1]], m[i-1][j]);
else
m[i][j] = m[i-1][j];
}
}
return m[n][capacity];
}
void test() {
// test values
//int M1[MAX_N] = {2, 4, 3, 2};
//int P1[MAX_N] = {45, 40, 25, 10};
int M1[MAX_N] = {6, 3, 2, 4};
int P1[MAX_N] = {50, 60, 40, 20};
int M2[MAX_N] = {23, 31, 29, 44, 53, 38, 63, 85, 89, 82};
int P2[MAX_N] = {92, 57, 49, 68, 60, 43, 67, 84, 87, 72};
// a)
printf("Recursion: %d\n",knapsackRecursive(MAX_CAPACITY, M1, P1, MAX_N));
printf("Recursion: %d\n",knapsackRecursive(MAX_CAPACITY, M2, P2, MAX_N));
printf("\n");
// b)
printf("Memoization: %d\n",knapsackMemoized(MAX_CAPACITY, M1, P1, MAX_N));
printf("Memoization: %d\n",knapsackMemoized(MAX_CAPACITY, M2, P2, MAX_N));
printf("\n");
// c)
printf("Dynamic Programming: %d\n",knapsackDynamic(MAX_CAPACITY, M1, P1, MAX_N));
printf("Dynamic Programming: %d\n",knapsackDynamic(MAX_CAPACITY, M2, P2, MAX_N));
}
int main() {
test();
}
This is the output I currently get. The recursive method should be supplying the correct result, but the dynamic programming one currently doesn't output the same. Memoization is not done yet, hence it doesn't output correctly either.
Recursion: 170
Recursion: 309
Memoization: 2686680
Memoization: 2686600
Dynamic Programming: 0
Dynamic Programming: 270
Process returned 25 (0x19) execution time : 0.269 s
Press any key to continue.
It turns out that the code I used for writing the dynamic programming part was supposed to work with int m[MAX_N+1][MAX_CAPACITY+1]; instead of int m[MAX_N][MAX_CAPACITY];.
Changing that has gotten me to a working code, if not really the code I wanted.