C: Why I am given similar things over multiple mallocs? - c

I wrote a demo on dynamic 2D arrays:
# include <stdio.h>
# include <stdlib.h>
# define getarray2d(obj, dst) int (* dst)[obj->w] = (int (*)[obj->w])&(obj->data)
typedef struct _myarray {
int *data;
size_t h;
size_t w;
} myarray;
myarray * mallocarray2d(size_t h, size_t w) {
myarray *arr = (myarray *)malloc(sizeof(myarray));
int *data = (int *)malloc(h * w * sizeof(int));
arr->data = data;
arr->h = h; arr->w = w;
}
void freearray2d(myarray *arr) {
free(arr->data); free(arr);
}
void printarray2d(myarray *arr) {
getarray2d(arr, array2d);
size_t h = arr->h; size_t w = arr->w; size_t i, j;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
printf("%12d ", array2d[i][j]);
}
printf("\n");
}
}
int main() {
myarray *arr = mallocarray2d(3, 4);
printarray2d(arr);
freearray2d(arr);
}
As expected, output is a "random" array:
F:\Users\23Xor\Desktop>a.exe
-695987216 555 3 0
4 0 -1651400550 268491609
-695968000 555 -695991984 555
But things became interesting after I ran it for multiple times:
F:\Users\23Xor\Desktop>a.exe
630939408 398 630915408 398
2037603443 1835365491 1666986547 1697539181
1140876664 1702259058 1952531570 977485153
F:\Users\23Xor\Desktop>a.exe
-1688379632 607 -1688403632 607
2037603443 1835365491 1666986547 1697539181
1140876664 1702259058 1952531570 977485153
F:\Users\23Xor\Desktop>a.exe
1305501456 532 1305477456 532
2037603443 1835365491 1666986547 1697539181
1140876664 1702259058 1952531570 977485153
F:\Users\23Xor\Desktop>a.exe
906452752 352 906428752 352
2037603443 1835365491 1666986547 1697539181
1140876664 1702259058 1952531570 977485153
F:\Users\23Xor\Desktop>a.exe
-1575002352 473 -1575026352 473
2037603443 1835365491 1666986547 1697539181
1140876664 1702259058 1952531570 977485153
F:\Users\23Xor\Desktop>a.exe
1594253072 518 1594229072 518
2037603443 1835365491 1666986547 1697539181
1140876664 1702259058 1952531570 977485153
F:\Users\23Xor\Desktop>a.exe
444751632 400 444727632 400
2037603443 1835365491 1666986547 1697539181
1140876664 1702259058 1952531570 977485153
Elements at pos (0, 1) (2, 1) (2, 3) are always equal, and elements at pos (0, 2) (0, 3) (1, 0) (1, 1) always remain 3 0 4 0
Is there a specific reason for this?
EDIT: I corrected my faults:
# include <stdio.h>
# include <stdlib.h>
# define getarray2d(obj, dst) int (* dst)[obj->w] = (int (*)[obj->w])(obj->data)
typedef struct _myarray {
void *data;
size_t h;
size_t w;
} myarray;
myarray * mallocarray2d(size_t h, size_t w) {
myarray *arr = (myarray *)malloc(sizeof(myarray));
void *data = malloc(h * w * sizeof(int));
arr->data = data;
arr->h = h; arr->w = w;
return arr;
}
myarray * callocarray2d(size_t h, size_t w) {
myarray *arr = (myarray *)malloc(sizeof(myarray));
void *data = calloc(h * w, sizeof(int));
arr->data = data;
arr->h = h; arr->w = w;
return arr;
}
void freearray2d(myarray *arr) {
free(arr->data); free(arr);
}
void printarray2d(myarray *arr) {
getarray2d(arr, array2d);
size_t h = arr->h; size_t w = arr->w; size_t i, j;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
printf("%12d ", array2d[i][j]);
}
printf("\n");
}
}
int main() {
myarray *arr = mallocarray2d(3, 4);
printarray2d(arr);
freearray2d(arr);
}
result:
F:\Users\23Xor\Desktop>a.exe
630939408 398 630915408 398
2037603443 1835365491 1666986547 1697539181
1140876664 1702259058 1952531570 977485153
F:\Users\23Xor\Desktop>a.exe
-1688379632 607 -1688403632 607
2037603443 1835365491 1666986547 1697539181
1140876664 1702259058 1952531570 977485153
F:\Users\23Xor\Desktop>a.exe
1305501456 532 1305477456 532
2037603443 1835365491 1666986547 1697539181
1140876664 1702259058 1952531570 977485153
F:\Users\23Xor\Desktop>a.exe
906452752 352 906428752 352
2037603443 1835365491 1666986547 1697539181
1140876664 1702259058 1952531570 977485153
F:\Users\23Xor\Desktop>a.exe
-1575002352 473 -1575026352 473
2037603443 1835365491 1666986547 1697539181
1140876664 1702259058 1952531570 977485153
F:\Users\23Xor\Desktop>a.exe
1594253072 518 1594229072 518
2037603443 1835365491 1666986547 1697539181
1140876664 1702259058 1952531570 977485153
F:\Users\23Xor\Desktop>a.exe
444751632 400 444727632 400
2037603443 1835365491 1666986547 1697539181
1140876664 1702259058 1952531570 977485153
the last 8 elements even stops changing.

Since reading uninitialized data invokes undefined behavior, there is no satisfactory answer to your question. The official answer is: don't do that, it's not allowed by the rules of the C language, so the C language makes no guarantees about what will happen if you break the rules. You might end up reading all-zeroes, or all-42's, or 0xDEADBEEF, or your program might crash, or any other conceivable behavior might occur, because the resulting executable is not considered a valid C program.
At a practical level, you're printing out the values of whatever leftover garbage happened to be present in the area of RAM that malloc(h * w * sizeof(int)) returned to you when you called it. Why those values happened to be there (and not something different) is a function of how your C runtime's heap allocator works, combined with whatever the heap was being used for previously in your program's startup (e.g. before main() was called)... you could probably work out why they end up in that particular state, if you want to spend several days stepping through the source code of your C runtime with a debugger and a notepad. It probably wouldn't be worth the effort, though.

Related

How do variable length arrays support numeric processing?

I am reading C The Complete Reference 4th edition by Herbert Schildt. In Chapter 4 - Arrays and Strings, it mentions "One major reason for the addition of variable-length arrays to C99 is to support numeric processing".
My question is: What is numeric processing? And how do variable-length arrays support numeric processing?
There are three places where variable-length arrays can appear:
Automatic local variables.
Dynamically allocated arrays.
Function parameters.
Automatic local variables can be problematic — they occupy stack space, and there's no portable way to find out whether there's enough stack space left to allocate the array you want to create. If there isn't enough space, the program will halt unilaterally; there is no way to recover from the error. This has many people up in arms against VLAs.
Dynamically allocated arrays are not problematic — though the notation is not singularly convenient. You can tell when an allocation fails and react appropriately.
Function parameters are where the flexibility comes into play — especially with 2D arrays (and higher dimensions too).
Prior to the introduction of VLAs, you had to either treat the array as a 1D vector and calculate the indexes manually or you had to write different functions for each different size of matrix — or, at least, for each different number of columns.
You could use:
enum { NCOLS = 8 };
static void dump_array(const char *tag, size_t nrows, int array[][NCOLS])
{
printf("%s: (%zux%d)\n", tag, nrows, NCOLS); // Note %zu vs %d!
for (size_t r = 0; r < nrows; r++)
{
for (size_t c = 0; c < NCOLS; c++)
printf(" %5d", array[r][c]);
putchar('\n');
}
}
That's fine as far as it goes, but if you want matrices with different numbers of columns, you have to write (and call) different functions.
An alternative was to use a large 1D vector and calculate the 2D subscripts in your code:
static void dump_array(const char *tag, size_t nrows, size_t ncols, int array[])
{
printf("%s: (%zux%zu)\n", tag, nrows, ncols);
for (size_t r = 0; r < nrows; r++)
{
for (size_t c = 0; c < ncols; c++)
printf(" %5d", array[r * ncols + c]);
putchar('\n');
}
}
With VLA notation for the arguments, though, you can write a single function to print any 2D matrix (of a given base type) and use direct subscript notation for maximum convenience:
static void dump_array(const char *tag, size_t nrows, size_t ncols, int array[nrows][ncols])
{
printf("%s: (%zux%zu)\n", tag, nrows, ncols);
for (size_t r = 0; r < nrows; r++)
{
for (size_t c = 0; c < ncols; c++)
printf(" %5d", array[r][c]);
putchar('\n');
}
}
There isn't much difference in the notation, but the gain in flexibility is enormous. You can write a single matrix multiplication function that will work for any sizes of matrix, for example, whereas before VLAs were available, only the 1D version could deal with arbitrary sizes of array.
The dynamic allocation is reasonably simple, though not entirely obvious:
/* SO 7531-3779 */
#include <stdio.h>
#include <stdlib.h>
static void dump_array(const char *tag, size_t rows, size_t cols, int array[rows][cols])
{
printf("%s (%zux%zu):\n", tag, rows, cols);
for (size_t r = 0; r < rows; r++)
{
printf("%2zu:", r);
for (size_t c = 0; c < cols; c++)
printf(" %5d", array[r][c]);
putchar('\n');
}
}
int main(void)
{
size_t rows = 13;
size_t cols = 8;
int (*array)[8] = malloc(sizeof(int [rows][cols]));
for (size_t r = 0; r < rows; r++)
{
int sign = -1;
for (size_t c = 0; c < cols; c++)
{
array[r][c] = sign * ((r + 1) * 100 + c + 1);
sign = -sign;
}
}
dump_array("Array 1", rows, cols, array);
free(array);
return 0;
}
Output:
Array 1 (13x8):
0: -101 102 -103 104 -105 106 -107 108
1: -201 202 -203 204 -205 206 -207 208
2: -301 302 -303 304 -305 306 -307 308
3: -401 402 -403 404 -405 406 -407 408
4: -501 502 -503 504 -505 506 -507 508
5: -601 602 -603 604 -605 606 -607 608
6: -701 702 -703 704 -705 706 -707 708
7: -801 802 -803 804 -805 806 -807 808
8: -901 902 -903 904 -905 906 -907 908
9: -1001 1002 -1003 1004 -1005 1006 -1007 1008
10: -1101 1102 -1103 1104 -1105 1106 -1107 1108
11: -1201 1202 -1203 1204 -1205 1206 -1207 1208
12: -1301 1302 -1303 1304 -1305 1306 -1307 1308
And the VLA notation can be used with fixed-size arrays — global or local — too. That is, ordinary arrays can be passed to functions that accept a VLA as long as you describe the arrays accurately:
/* SO 7531-3779 */
#include <stdio.h>
#include <stdlib.h>
static void dump_array(const char *tag, size_t rows, size_t cols, int array[rows][cols])
{
printf("%s (%zux%zu):\n", tag, rows, cols);
for (size_t r = 0; r < rows; r++)
{
printf("%2zu:", r);
for (size_t c = 0; c < cols; c++)
printf(" %5d", array[r][c]);
putchar('\n');
}
}
/* Created by: gen_matrix -r 9 -c 5 -L -9999 -H +9999 -x -n matrix1 -w5 -E */
/* Random seed: 0x7F3F1FA0 */
int matrix1[9][5] =
{
{ 9337, 5320, 5059, 1115, 14, },
{ -7514, -1643, 8461, 1613, 6968, },
{ 2469, 8307, -8045, 2327, -7862, },
{ 8174, -7062, 666, -3480, 1836, },
{ -2400, -7863, -1859, 2436, -6840, },
{ 5819, -4112, -2037, 9005, -9748, },
{ 823, -9687, 1245, -2074, 3741, },
{ 4812, -9254, -6365, -1263, -9265, },
{ -9400, -5479, -3756, -7417, -5726, },
};
enum { MATRIX1_ROWS = 9, MATRIX1_COLS = 5 };
int main(void)
{
/* Created by: gen_matrix -E -r 13 -c 8 -H 999 -L -999 -i -w4 -n matrix2 */
/* Random seed: 0x64347CFE */
int matrix2[13][8] =
{
{ -27, -268, 73, 112, -148, 407, -411, 418, },
{ -782, 368, -306, -830, -851, 9, 505, 33, },
{ -558, -979, 471, 376, -290, -270, -910, 812, },
{ -374, 201, 454, 966, -39, 653, -747, -664, },
{ 322, 385, -141, -326, 37, 941, -298, -281, },
{ 529, 68, -995, -30, -942, -670, 563, -244, },
{ 773, 46, -315, -363, 732, 218, 230, 536, },
{ 566, -164, -493, 568, -256, -196, -635, -387, },
{ 452, -348, 79, 103, -416, -756, 688, -473, },
{ -294, -641, 530, -307, 508, 878, -786, -745, },
{ 427, 462, -229, 253, 116, -804, -72, -35, },
{ -776, 290, 158, 154, 662, -621, 576, 388, },
{ 999, -684, -207, -506, 708, -949, 149, -969, },
};
enum { MATRIX2_ROWS = 13, MATRIX2_COLS = 8 };
dump_array("Matrix 1", MATRIX1_ROWS, MATRIX1_COLS, matrix1);
dump_array("Matrix 2", MATRIX2_ROWS, MATRIX2_COLS, matrix2);
return 0;
}
Output:
Matrix 1 (9x5):
0: 9337 5320 5059 1115 14
1: -7514 -1643 8461 1613 6968
2: 2469 8307 -8045 2327 -7862
3: 8174 -7062 666 -3480 1836
4: -2400 -7863 -1859 2436 -6840
5: 5819 -4112 -2037 9005 -9748
6: 823 -9687 1245 -2074 3741
7: 4812 -9254 -6365 -1263 -9265
8: -9400 -5479 -3756 -7417 -5726
Matrix 2 (13x8):
0: -27 -268 73 112 -148 407 -411 418
1: -782 368 -306 -830 -851 9 505 33
2: -558 -979 471 376 -290 -270 -910 812
3: -374 201 454 966 -39 653 -747 -664
4: 322 385 -141 -326 37 941 -298 -281
5: 529 68 -995 -30 -942 -670 563 -244
6: 773 46 -315 -363 732 218 230 536
7: 566 -164 -493 568 -256 -196 -635 -387
8: 452 -348 79 103 -416 -756 688 -473
9: -294 -641 530 -307 508 878 -786 -745
10: 427 462 -229 253 116 -804 -72 -35
11: -776 290 158 154 662 -621 576 388
12: 999 -684 -207 -506 708 -949 149 -969

Some values are printing extra times the i (i = 0; i < 10; i++) that i don't want . While using for loop in C

I want an output that prints cube of odd numbers printing in a triangular order up to base number 10, like this.
1
27 27
125 125 125
343 343 343 343
.....
but my program prints
1
27 27 27
125 125 125 125 125
343 343 343 343 343 343 343
.....
it prints extra values.
I tried whatever possible that I learned, and also adding extra for loops...
#include<stdio.h>
#include<conio.h>
void main()
{
clrscr();
int a;
int i,j;
a=1;
for(i=0;i<10;i++)
{
for(j=0;j<i;j++)
{
if(i%2!=0)
{
a=i*i*i;
printf("%d ",a);
}
}
printf("\n");
}
getch();
}
This is what I want...
1
27 27
125 125 125
343 343 343 343
No errors by the compiler, only those extra values printing on the Output screen.
this is ok?
#include<stdio.h>
#include<conio.h>
void main()
{
int a = 1;
for (int i = 1; i < 10; i+=2)
{
for (int j = 0; j < i - i/2; j++)
{
a = i * i * i;
printf("%d ", a);
}
printf("\n");
}
getchar();
}
1
27 27
125 125 125
343 343 343 343
729 729 729 729 729
This solution will give you an easy to understand way to do the printing. The trick consists in using enough variables to update, the number of times you have to print at each line, and the computations to do de cubes:
#include <stdio.h>
int main()
{
int a = 1, line;
for (line = 0; line < 10; line++) {
int cube = a*a*a, item_in_line;
char *sep = ""; /* no separator at the beginning */
for (item_in_line = 0;
item_in_line <= line;
item_in_line++) {
printf("%s%d", sep, cube);
sep = ", "; /* from now on, we print commas */
}
printf("\n");
a += 2; /* get next number to cube */
}
}
This will print:
1
27, 27
125, 125, 125
343, 343, 343, 343
729, 729, 729, 729, 729
1331, 1331, 1331, 1331, 1331, 1331
2197, 2197, 2197, 2197, 2197, 2197, 2197
3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375
4913, 4913, 4913, 4913, 4913, 4913, 4913, 4913, 4913
6859, 6859, 6859, 6859, 6859, 6859, 6859, 6859, 6859, 6859

I am trying to implement memory allocation using worst fit algorithm. Error while displaying the output

CODE
#include<stdio.h>
#include<string.h>
void worst_fit(int space[],int requests[],int m,int n)
{
int cp[m];
int i,j;
for(i=0;i<m;i++)
cp[i]=space[i];
int allocation[n];
memset(allocation,-1,sizeof(allocation));
int check[m];
for(i=0;i<n;i++)
{
memset(check,0,sizeof(check));
int max=-1;
for(j=0;j<m;j++)
{
if(requests[i]<=space[j])
{
check[j]=1;
if(max==-1)
max=j;
}
}
//printf("%d \n",requests[i]);
for(j=0;j<m;j++)
{
if(check[j]!=0)
{
if(space[j]>space[max])
max=j;
}
}
//printf("%d \n",requests[i]);
allocation[i]=cp[max];//copy of space should done: pending
printf("%d %d -\n",requests[i],space[max]);
space[max]=space[max]-requests[i];
printf("%d %d\n",requests[i],space[max]);
}
printf("\nProcess No.\tProcess Size\tBlock no.\n");
for (int i = 0; i < n; i++)
{
//printf("%d\n",requests[i]);
printf("%d \t\t%d \t\t",i+1,requests[i]);
if (allocation[i] != -1)
printf("%d \n",allocation[i]);
else
printf("Not Allocated \n");
}
}
int main()
{
int i;
int s[]={100, 500, 200, 300, 600};
int r[]={212, 417, 112, 426};
int m = sizeof(s) / sizeof(s[0]);
int n = sizeof(r) / sizeof(r[0]);
worst_fit(s,r,m,n);
}
The output is showing an unexpected error due to the below snippet
printf("%d %d -\n",requests[i],space[max]);
space[max]=space[max]-requests[i];
printf("%d %d\n",requests[i],space[max]);
OUTPUT for the above will be
212 600 -
212 388
417 500 -
417 83
112 388 -
112 276
426 426 -
0 0
I don't understand how 426 which is stored in requests[i] is reduced to 0.
The complete output is
212 600 -
212 388
417 500 -
417 83
112 388 -
112 276
426 426 -
0 0
Process No. Process Size Block no.
1 212 600
2 417 500
3 112 600
4 0 Not Allocated

Is not stack'd, malloc'd or (recently) free'd, when the amount of operations gets large

This is my code (sorry, it's long, but there is a lot of repeating code).
{Description}
Sorting algortihm testing program using pseudo randomly
generated number array. User can specify array length,
its min and max elements, the least number of repeating
values. User can also choose how many arrays to be tested.
1 /*=============================================================================
2 |
3 | Assignment: Program 12
4 |
8 | Class: Programming Basics
9 | Date: December 13th, 2017
10 |
11 | Language: GNU C (using gcc on Lenovo Y50-70, OS: Arch Linux x86_64)
12 | Version: 0.0
13 | To Compile: gcc -Wall -g -std=c11 pratybos12.c -o pratybos12
14 |
15 +-----------------------------------------------------------------------------
16 |
17 | Description: Sorting algortihm testing program using pseudo randomly
18 | generated number array. User can specify array length,
19 | its min and max elements, the least number of repeating
20 | values. User can also choose how many arrays to be tested.
21 |
22 | Input: Command line input by user
23 |
24 | Output: Prompt messages, validation errors and final results
25 | are displayed one per line to the standard output.
26 | The output is each algorithm's each iteration, with
27 | comparison and assignment counts, and also processor
28 | clock times and average completion time, in seconds.
29 | Finally, the average data of each algorithm is presented.
30 | At the end, the algorithms are sorted from best to worst
31 | by their average time.
32 |
33 | Version
34 | updates: Currently this is the intial version
35 |
36 +===========================================================================*/
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <time.h>
41
42 #include "dbg.h"
43
44 #include "helpers.h"
45 #include "test_algorithm.h"
46
47 #include "bubble_sort_a.h"
48 #include "bubble_sort_b.h"
49 #include "bubble_sort_c.h"
50 #include "bubble_sort_d.h"
51 #include "bubble_sort_e.h"
52 #include "bubble_sort_e_and_f.h"
53 #include "bubble_sort_f.h"
54 #include "bubble_sort_b_and_c.h"
55 #include "bubble_sort_b_and_e.h"
56 #include "bubble_sort_b_and_f.h"
57 #include "bubble_sort_c_and_e.h"
58 #include "bubble_sort_c_and_f.h"
59 #include "bubble_sort_b_and_e_and_f.h"
60 #include "bubble_sort_b_and_c_and_e_and_f.h"
61 #include "insertion_sort.h"
62 #include "quicksort_pivot_first.h"
63 #include "selection_sort.h"
64 #include "top_down_merge_sort.h"
65
66 #define MAX_ITER 100
67 #define MAX_ALGO 100
68
69
70 typedef struct {
71 char* pointerName;
72 int pointerMemory;
73 } PointerStats;
74
75 typedef struct {
76 PointerStats* memJournal;
77 int JournalPointerCount;
78 int memUsed;
79 int memUsedByJournal;
80 } MemoryStats;
81
82
83 typedef struct {
84 int no;
85 int is_sorted;
86 int comp_count;
87 int assign_count;
88 double clocks_total;
89 double time_spent;
90 } Iteration;
91
92 typedef struct {
93 char* type;
94 char* complexity;
95 int iter_count;
96 int rank;
97 int avg_comp;
98 int avg_assign;
99 double avg_clocks;
100 double avg_time;
101 Iteration* iterations[MAX_ITER];
102 } Algorithm;
103
104 typedef struct {
105 char* date;
106 char* arch;
107 char* compiler;
108 Algorithm* algorithms[MAX_ALGO];
109 } Results;
110
111 // a typedef creates a fake type, in this
112 // case for a sort function pointer
113 typedef int* (*sort_pointer)(int* target, int size);
114
115 // function pointer to a quicksort function
116 typedef int* (*quicksort_pointer)(int* target, int first, int last);
117
118 // function pointer to a mergesort function
119 typedef void (*mergesort_pointer)(int* target, int* working_array, int size);
120
121
122 void filldata(int* data, int size, int min, int max, int repeat);
123 void test_sort( int* data, int size, sort_pointer func, Algorithm* Algo, int no);
124 void test_quicksort( int* data, int size, quicksort_pointer func, Algorithm* Algo, int no);
125 void test_mergesort( int* data, int size, mergesort_pointer func, Algorithm* Algo, int no);
126 void print_algo(Algorithm* Algo);
127 void calculate_average(Algorithm* Algo);
128 Algorithm** rank_algorithms(Algorithm** target, int first, int last);
129
130 MemoryStats memoryStats;
131
132 int array_count;
133
134 int main(int argc, char* argv[])
135 {
136 srand(time(NULL));
137
138 Results* Res = malloc(sizeof(Results));
139
140 Res->date = "2017-12-16";
141 Res->arch = "Arch Linux x86_64";
142 Res->compiler = "gcc";
143
144 // creating algorithm structures
145 Algorithm* Algo1 = malloc(sizeof(Algorithm));
146 Algo1->type = "bubble_sort_a";
147 Algo1->complexity = "O (n^2)";
148
149 Algorithm* Algo2 = malloc(sizeof(Algorithm));
150 Algo2->type = "bubble_sort_b";
151 Algo2->complexity = "O (n^2)";
152
153 Algorithm* Algo3 = malloc(sizeof(Algorithm));
154 Algo3->type = "bubble_sort_c";
155 Algo3->complexity = "O (n^2)";
156
157 Algorithm* Algo4 = malloc(sizeof(Algorithm));
158 Algo4->type = "bubble_sort_d";
159 Algo4->complexity = "O (n^2)";
160
161 Algorithm* Algo5 = malloc(sizeof(Algorithm));
162 Algo5->type = "bubble_sort_e";
163 Algo5->complexity = "O (n^2)";
164
165 Algorithm* Algo6 = malloc(sizeof(Algorithm));
166 Algo6->type = "bubble_sort_f";
167 Algo6->complexity = "O (n^2)";
168
169 Algorithm* Algo7 = malloc(sizeof(Algorithm));
170 Algo7->type = "bubble_sort_b_and_c";
171 Algo7->complexity = "O (n^2)";
172
173 Algorithm* Algo8 = malloc(sizeof(Algorithm));
174 Algo8->type = "bubble_sort_b_and_e";
175 Algo8->complexity = "O (n^2)";
176
177 Algorithm* Algo9 = malloc(sizeof(Algorithm));
178 Algo9->type = "bubble_sort_b_and_f";
179 Algo9->complexity = "O (n^2)";
180
181 Algorithm* Algo10 = malloc(sizeof(Algorithm));
182 Algo10->type = "bubble_sort_c_and_e";
183 Algo10->complexity = "O (n^2)";
184
185 Algorithm* Algo11 = malloc(sizeof(Algorithm));
186 Algo11->type = "bubble_sort_c_and_f";
187 Algo11->complexity = "O (n^2)";
188
189 Algorithm* Algo12 = malloc(sizeof(Algorithm));
190 Algo12->type = "bubble_sort_e_and_f";
191 Algo12->complexity = "O (n^2)";
192
193 Algorithm* Algo13 = malloc(sizeof(Algorithm));
194 Algo13->type = "bubble_sort_b_and_e_and_f";
195 Algo13->complexity = "O (n^2)";
196
197 Algorithm* Algo14 = malloc(sizeof(Algorithm));
198 Algo14->type = "bubble_sort_b_and_c_and_e_and_f";
199 Algo14->complexity = "O (n^2)";
200
201 Algorithm* Algo15 = malloc(sizeof(Algorithm));
202 Algo15->type = "quicksort";
203 Algo15->complexity = "O (n logn n)";
204
205 Algorithm* Algo16 = malloc(sizeof(Algorithm));
206 Algo16->type = "insertion_sort";
207 Algo16->complexity = "O (2n)";
208
209 Algorithm* Algo17 = malloc(sizeof(Algorithm));
210 Algo17->type = "selection_sort";
211 Algo17->complexity = "O (2n)";
212
213 Algorithm* Algo18 = malloc(sizeof(Algorithm));
214 Algo18->type = "top down merge sort";
215 Algo18->complexity = "O (n log n)";
216
217 Res->algorithms[0] = Algo1;
218 Res->algorithms[1] = Algo2;
219 Res->algorithms[2] = Algo3;
220 Res->algorithms[3] = Algo4;
221 Res->algorithms[4] = Algo5;
222 Res->algorithms[5] = Algo6;
223 Res->algorithms[6] = Algo7;
224 Res->algorithms[7] = Algo8;
225 Res->algorithms[8] = Algo9;
226 Res->algorithms[9] = Algo10;
227 Res->algorithms[10] = Algo11;
228 Res->algorithms[11] = Algo12;
229 Res->algorithms[12] = Algo13;
230 Res->algorithms[13] = Algo14;
231 Res->algorithms[14] = Algo15;
232 Res->algorithms[15] = Algo16;
233 Res->algorithms[16] = Algo17;
234 Res->algorithms[17] = Algo18;
235
236 memoryStats.memJournal = malloc(10 * sizeof(int));
237
238 memoryStats.memUsedByJournal = 10;
239
240 memoryStats.JournalPointerCount = 0;
241
242 printf("Mem used total: %d\n", memoryStats.memUsed);
243
244 int size;
245 int min;
246 int max;
247 int repeat;
248
249 array_count = get_pos_num("How many arrays would you like to test? > ", 0);
250 size = get_pos_num("What is the size of each array? > ", 0);
251 min = get_pos_num("What is the minimum number in each array? > ", 0);
252 max = get_pos_num("What is the maximum number in each array? > ", 0);
253
254 while (1) {
255 printf("How many repeating values there will be AT LEAST? > ");
256 if (scanf("%d", &repeat) == 1 && repeat >= 0
257 && repeat <= (max - min + 1) && getchar() == '\n') {
258 break;
259 } else {
260 while (getchar() != '\n')
261 ;
262 printf("Please enter a positive integer or zero, which is not "
263 "greater than the "
264 "size of the array\n");
265 }
266 }
267
268 for (int i = 0; i < array_count; i++) {
269 int* data = malloc(size * sizeof(int));
270
271 filldata(data, size, min, max, repeat);
272 if (data == NULL)
273 die("Atminties problema");
274
275 printf("i: %d", i);
276 print_array(data, size, "Your generated numbers:");
277 //---------------------------USING FUNCTION POINTERS-----------------//
278
279 test_sort(data, size, &bubble_sort_a, Algo1, i + 1);
280 test_sort(data, size, &bubble_sort_b, Algo2, i + 1);
281 test_sort(data, size, &bubble_sort_c, Algo3, i + 1);
282 test_sort(data, size, &bubble_sort_d, Algo4, i + 1);
283 test_sort(data, size, &bubble_sort_e, Algo5, i + 1);
284 test_sort(data, size, &bubble_sort_f, Algo6, i + 1);
285 test_sort(data, size, &bubble_sort_b_and_c, Algo7, i + 1);
286 test_sort(data, size, &bubble_sort_b_and_e, Algo8, i + 1);
287 test_sort(data, size, &bubble_sort_b_and_f, Algo9, i + 1);
288 test_sort(data, size, &bubble_sort_c_and_e, Algo10, i + 1);
289 test_sort(data, size, &bubble_sort_c_and_f, Algo11, i + 1);
290 test_sort(data, size, &bubble_sort_e_and_f, Algo12, i + 1);
291 test_sort(data, size, &bubble_sort_b_and_e_and_f, Algo13, i + 1);
292 test_sort(data, size, &bubble_sort_b_and_c_and_e_and_f, Algo14, i + 1);
293
294 test_sort(data, size, &bubble_sort_c_and_f, Algo15, i + 1);
295 test_sort(data, size, &bubble_sort_e_and_f, Algo16, i + 1);
296 test_sort(data, size, &bubble_sort_b_and_e_and_f, Algo17, i + 1);
297 test_sort(data, size, &bubble_sort_b_and_c_and_e_and_f, Algo18, i + 1);
298
299
300 free(data);
301 }
302
303 calculate_average(Algo1);
304 calculate_average(Algo2);
305 calculate_average(Algo3);
306 calculate_average(Algo4);
307 calculate_average(Algo5);
308 calculate_average(Algo6);
309 calculate_average(Algo7);
310 calculate_average(Algo8);
311 calculate_average(Algo9);
312 calculate_average(Algo10);
313 calculate_average(Algo11);
314 calculate_average(Algo12);
315 calculate_average(Algo13);
316 calculate_average(Algo14);
317 calculate_average(Algo15);
318 calculate_average(Algo16);
319 calculate_average(Algo17);
320 calculate_average(Algo18);
321
322
323 for (int i = 0; i < 18; i++) {
324 print_algo(Res->algorithms[i]);
325 }
326
327
328 Algorithm** target = malloc(18 * sizeof(Algorithm));
329
330 target[0] = Algo1;
331 target[1] = Algo2;
332 target[2] = Algo3;
333 target[3] = Algo4;
334 target[4] = Algo5;
335 target[5] = Algo6;
336 target[6] = Algo7;
337 target[7] = Algo8;
338 target[8] = Algo9;
339 target[9] = Algo10;
340 target[10] = Algo11;
341 target[11] = Algo12;
342 target[12] = Algo13;
343 target[13] = Algo14;
344 target[14] = Algo15;
345 target[15] = Algo16;
346 target[16] = Algo17;
347 target[17] = Algo18;
348
349 target = rank_algorithms(target, 0, 17);
350
351 printf("Fastest algorithms (ranking):\n");
352 printf("=============================\n");
353
354 for (int i = 0; i < 18; i++) {
355 printf("%d. ", i + 1);
356 printf("%s\n", target[i]->type);
357 printf("Average time: %f\n", target[i]->avg_time);
358 printf("---------------------------------\n");
359 }
360
361 printf("================================\n");
362 printf("Date: %s\n", Res->date);
363 printf("Architecture: %s\n", Res->arch);
364 printf("Compiler: %s\n", Res->compiler);
365 printf("================================\n");
366
367 printf("Mem used total: %d\n", memoryStats.memUsed);
368
369
370 free(Res);
371
372
373 for (int i = 0; i < array_count; i++) {
374 free(Algo1->iterations[i]);
375 }
376 free(Algo1);
377
378 for (int i = 0; i < array_count; i++) {
379 free(Algo2->iterations[i]);
380 }
381 free(Algo2);
382
383 for (int i = 0; i < array_count; i++) {
384 free(Algo3->iterations[i]);
385 }
386 free(Algo3);
387
388 for (int i = 0; i < array_count; i++) {
389 free(Algo4->iterations[i]);
390 }
391 free(Algo4);
392
393 for (int i = 0; i < array_count; i++) {
394 free(Algo5->iterations[i]);
395 }
396 free(Algo5);
397
398 for (int i = 0; i < array_count; i++) {
399 free(Algo6->iterations[i]);
400 }
401 free(Algo6);
402
403 for (int i = 0; i < array_count; i++) {
404 free(Algo7->iterations[i]);
405 }
406 free(Algo7);
407
408 for (int i = 0; i < array_count; i++) {
409 free(Algo8->iterations[i]);
410 }
411 free(Algo8);
412
413 for (int i = 0; i < array_count; i++) {
414 free(Algo9->iterations[i]);
415 }
416 free(Algo9);
417
418 for (int i = 0; i < array_count; i++) {
419 free(Algo10->iterations[i]);
420 }
421 free(Algo10);
422
423 for (int i = 0; i < array_count; i++) {
424 free(Algo11->iterations[i]);
425 }
426 free(Algo11);
427
428 for (int i = 0; i < array_count; i++) {
429 free(Algo12->iterations[i]);
430 }
431 free(Algo12);
432
433 for (int i = 0; i < array_count; i++) {
434 free(Algo13->iterations[i]);
435 }
436 free(Algo13);
437
438 for (int i = 0; i < array_count; i++) {
439 free(Algo14->iterations[i]);
440 }
441 free(Algo14);
442
443 for (int i = 0; i < array_count; i++) {
444 free(Algo15->iterations[i]);
445 }
446 free(Algo15);
447
448 for (int i = 0; i < array_count; i++) {
449 free(Algo16->iterations[i]);
450 }
451 free(Algo16);
452
453 for (int i = 0; i < array_count; i++) {
454 free(Algo17->iterations[i]);
455 }
456 free(Algo17);
457
458 for (int i = 0; i < array_count; i++) {
459 free(Algo18->iterations[i]);
460 }
461 free(Algo18);
462
463 free(target);
464 free(memoryStats.memJournal);
465 }
466
467
468 void filldata(int* data, int size, int min, int max, int repeat)
469 {
470 int i;
471
472 for (i = 0; i < size; i++) {
473 data[i] = min + rand() % (max - min + 1);
474 }
475
476 if (repeat > 1) {
477 int repeat_value = min + rand() % (max - min + 1);
478
479 int indexes[repeat];
480
481 int x;
482
483 // Non-duplicate number generation
484
485 i = 0;
486 while (i < repeat) {
487 int index = rand() % size;
488
489 for (x = 0; x < i; x++) {
490 if (indexes[x] == index) {
491 break;
492 }
493 }
494 if (x == i) {
495 indexes[i++] = index;
496 }
497 }
498
499 for (i = 0; i < repeat; i++) {
500 data[indexes[i]] = repeat_value;
501 }
502 }
503 }
504
505
506 void test_sort(int* data, int size, sort_pointer func, Algorithm* Algo, int no)
507 {
508
509 count_ncomp = 0;
510 count_assign = 0;
511
512 begin = clock();
513
514 int* target = NULL;
515 target = malloc(size * sizeof(int));
516 if (!target)
517 die("Memory error.");
518
519 memcpy(target, data, size * sizeof(int));
520
521 Iteration* Iter = malloc(sizeof(Iteration));
522 if (Iter == NULL) {
523 exit(1);
524 }
525 Iter->no = no;
526
527 if (is_sorted(func(target, size), size)) {
528 end = clock();
529 clocks = (double)(end - begin);
530 time_spent = clocks / CLOCKS_PER_SEC;
531
532 Iter->is_sorted = 1;
533 Iter->comp_count = count_ncomp;
534 Iter->assign_count = count_assign;
535 Iter->clocks_total = clocks;
536 Iter->time_spent = time_spent;
537 } else {
538 Iter->is_sorted = 0;
539
540 };
541
542 Algo->iterations[no - 1] = Iter;
543
544 if (target == NULL) {
545 debug("Target is NULL");
546 }
547
548 free(target);
549 }
550
551
552 void print_algo(Algorithm* Algo)
553 {
554
555 printf("Algorithm type: %s\n", Algo->type);
556 printf("Time complexity: %s\n", Algo->complexity);
557 printf("----------------------------------\n");
558 for (int i = 0; i < array_count; i++) {
559 if (!Algo->iterations[i]->is_sorted) {
560 printf("Not sorted");
561 } else {
562 printf("no: %d\n", Algo->iterations[i]->no);
563 printf("is_sorted: True\n");
564 printf("comp_count: %d\n", Algo->iterations[i]->comp_count);
565 printf("assign count: %d\n", Algo->iterations[i]->assign_count);
566 printf("clocks total: %f\n", Algo->iterations[i]->clocks_total);
567 printf("time spent: %f\n", Algo->iterations[i]->time_spent);
568 }
569 printf("----------------------------------\n");
570 }
571 printf("Iteration count: %d\n", Algo->iter_count);
572 printf("Average compare count: %d\n", Algo->avg_comp);
573 printf("Average assign count: %d\n", Algo->avg_assign);
574 printf("Average clocks: %f\n", Algo->avg_clocks);
575 printf("Average time spent: %f\n", Algo->avg_time);
576
577 printf("===================================\n");
578 }
579
580 void calculate_average(Algorithm* Algo)
581 {
582 int sum_comp = 0;
583 int sum_assign = 0;
584 double sum_clocks = 0;
585 double sum_time = 0;
586 int sorted_count = array_count;
587
588 for (int i = 0; i < array_count; i++) {
589
590 debug("is sorted %d", Algo->iterations[i]->is_sorted);
591 debug("Array count: %d", i);
592
593 if (!Algo->iterations[i]->is_sorted) {
594 sorted_count--;
595 } else {
596 sum_comp += Algo->iterations[i]->comp_count;
597 sum_assign += Algo->iterations[i]->assign_count;
598 sum_clocks += Algo->iterations[i]->clocks_total;
599 sum_time += Algo->iterations[i]->time_spent;
600 }
601 }
602 if (sorted_count > 0) {
603 Algo->avg_comp = sum_comp / sorted_count;
604 Algo->avg_assign = sum_assign / sorted_count;
605 Algo->avg_clocks = (double)(sum_clocks / sorted_count);
606 Algo->avg_time = (double)(sum_time / sorted_count);
607 Algo->iter_count = sorted_count;
608 }
609 }
610
611 Algorithm** rank_algorithms(Algorithm** target, int first, int last)
612 {
613
614 Algorithm* temp;
615 int pivot, j, i;
616
617 if (first < last) {
618 pivot = first;
619 i = first;
620 j = last;
621
622 while (i < j) {
623 while (
624 target[i]->avg_time <= target[pivot]->avg_time && i < last) {
625 i++;
626 }
627 while (target[j]->avg_time > target[pivot]->avg_time) {
628 j--;
629 }
630 if (i < j) {
631 temp = target[i];
632 target[i] = target[j];
633 target[j] = temp;
634 }
635 }
636
637 temp = target[pivot];
638 target[pivot] = target[j];
639 target[j] = temp;
640
641 rank_algorithms(target, first, j - 1);
642 rank_algorithms(target, j + 1, last);
643 }
644 return target;
645 }
646
What I can successfully do (running a program):
How many arrays would you like to test? > 100
What is the size of each array? > 10
What is the minimum number in each array? > 1
What is the maximum number in each array? > 10
How many repeating values there will be AT LEAST? > 0
What I can't do:
How many arrays would you like to test? > 1000
What is the size of each array? > 10
What is the minimum number in each array? > 1
What is the maximum number in each array? > 10
How many repeating values there will be AT LEAST? > 0
The problem is when there are 1000 arrays to be tested (instead of 100).
This is the same error I get:
DEBUG pratybos12.c:590: is sorted 1
DEBUG pratybos12.c:591: Array count: 919
==5798== Invalid read of size 4
==5798== at 0x10A646: calculate_average (pratybos12.c:590)
==5798== by 0x1096F5: main (pratybos12.c:313)
==5798== Address 0x2d2d2d2d2d2d2d31 is not stack'd, malloc'd or (recently) free'd
==5798==
==5798==
==5798== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==5798== General Protection Fault
==5798== at 0x10A646: calculate_average (pratybos12.c:590)
==5798== by 0x1096F5: main (pratybos12.c:313)
The question is, how to even start debugging it, ie where the problem might be.
A few notes:
(1) When I run it with 100 arrays (first case), Valgrind reports that all memory is successfully freed, no leaks occur.
(2) I had a "double free or corruption error" in line 300:
300 free(data);
but I turned it off by setting MALLOC_CHECK_ to 0.
The size of Algorithm.iterations is MAX_ITER which is 100. And then you access Algorithm.iterations elements up to 1000th. This is undefined behavior.
Algorithm** target = malloc(18 * sizeof(Algorithm)); is wrong for sure. The type of target should be Algorithm *.

Finding all combinations of a^2 + b^2 in C

I'm trying to find all combinations of x, where x = a^2 + b^2, and x is between 100 and 999.
So far i've got:
#include <stdio.h>
#include <stdlib.h>
#define MAX 31 // given that 31^2 = 961
int main(){
int i = 0;
int poss_n[] = {0};
for (int a=0; a <= MAX; a++){
for (int b=0; b <= MAX; b++){
if (a*a + b*b >= 100 && a*a + b*b <= 999){
poss_n[i] = a*a + b*b;
printf("%i\n", poss_n[i]);
i++;
}
}
}
}
However it's giving only partially correct output, and also prematurely ends with segmentation fault 11:
100
1380405074
144
169
196
225
256
289
324
361
400
441
484
529
576
625
676
729
784
841
900
961
101
122
145
170
197
226
257
290
325
362
401
442
485
530
577
626
677
730
785
842
901
962
104
125
148
173
200
229
260
293
328
365
404
445
488
533
580
629
680
733
788
845
904
965
109
130
153
178
205
234
265
298
333
370
409
450
493
538
585
634
685
738
793
850
909
970
116
137
160
185
212
241
272
305
340
377
416
457
500
545
592
641
692
745
800
857
916
977
106
125
146
169
194
221
250
281
314
349
386
425
466
509
554
601
650
701
754
809
866
925
986
100
117
136
157
180
205
232
261
292
325
360
397
436
477
520
Segmentation fault: 11
What modifications should I make to my code?
UPDATE
Other than the the array issue, is there anything else wrong with my code? for instance it's still printing 100 as the first value which doesn't appear to be any combination of a^2 + b^2, even when b = 0.
UPDATE 2
Never mind, forgot a = 10, b = 0, which would be 100.
Try:
int poss_n[(MAX + 1) * (MAX + 1)] = {0};
This way you allocate enough memory to store your answers.
Your error is that you don't allocate place to save you results.
try this:
#include <stdio.h>
#include <stdlib.h>
#define MAX 31 // given that 31^2 = 961
int main(){
int i = 0;
int poss_n[(MAX + 1) * (MAX + 1)] = {0}; //<<- Give it a size
int result; //<<- Using this to reduce calculation of the value multiple times.
for (int a=0; a <= MAX; a++){
for (int b=0; b <= MAX; b++){
result = a*a + b*b;
if (result >= 100 && result <= 999){
poss_n[i] = result ;
printf("%i\n", result);
i++;
}
}
}
}
int poss_n[] = {0};
This will define array holding one element, leading to Segfault later when you will try to access element with index > 1
Try this , it will work
#include <stdio.h>
#include <stdlib.h>
#define MAX 31 // given that 31^2 = 961
int main(){
int i = 0;
int poss_n[301];
int a,b;
for (a=0; a <= MAX; a++){
for (b=0; b <= MAX; b++){
if (a*a + b*b >= 100 && a*a + b*b <= 999){
poss_n[i] = a*a + b*b;
printf("%i\t i = %d , a = %d , b = %d\n", poss_n[i],i,a,b);
i++;
}
}
}
}
Lots of answers here, but none quite accurate.
Ff we assume that only unique output is printed out, loop should look like this (as Roee Gavirel stated):
for (int a=0; a <= MAX; a++){
for (int b=a; b <= MAX; b++){
poss_n will hold this number of elements: (32+(32-1)+(32-2)+..+1)=1/2*32*(32+1)
So it should be defined as:
int elements = MAX+1;
int *poss_n = (int*)malloc ((1/2)*(elements)*(elements+1));
It will have more elements because of rule 100< value <999, but without that rule it will hold exact number of elements.
As others already said you allocate too few space on stack. Stack goes from high addresses decreasing. So at first You overwrite the stack data corrupting it and then You reach the end of the stack and You try to write to a memory space not allocated to You, or not allocated at all. The CPU generates an exception and that's why the Segmentation fault error occurs.
Also You could allocate some memory with malloc(3) on the heap and not on the stack, and when You found more result You can extend using realloc. It uses more system CPU resources, but reduces the memory overallocation.
On some un*ces You can also dynamically allocate memory on stack, using the alloca(3) function. It behaves very similar then some_type array[some_value], but some_value can be calculated runtime and not compile time.
Also You can use C++ STL containers, like vector and list and You can push the found elements. The allocate memory segments automatically on the heap.
Some comments:
Addition can be used instead of multiplication counting squares. (a+1)^2 - a^2 = 2a + 1. So add (a<<1) + 1 to a temp variable starting from 0. Similar can be applied to b.
Also from the inner loop can be jumped with break if the sum is over 999. You do not need to check the remaining values.
The value b could start from (int)sqrt(100-a*a) (or use a temp varible to keep track of the first b value) to reduce the number of inner loops.

Resources