Reallocation/allocation of memory in c - c

What the program does:
Reads from a file a matrix (2d Array) with nrRows rows and nrColomns colomns.
All elements of the matrix are int numbers between [0,100).
The program has to rearrange all of the elements inside the matrix such that each element is equal to the index of the row it is in.
ex. 5 will be on line(row) 5, 58 on row 58.
The result is written in a file.
I need to use only 1 matrix and all memory is allocated dynamically.
If I have to add or erase elements, I also readjust the memory of the matrix.
Also, I need to keep the shape of a matrix.
ex. 3 rows with 2 colomns. NOT 3 rows where row 1 has 1 colomn, row 2 has 3 colomns, etc..
I think reallocation doesn't work in my c program. The program itself works fine.
Help?
#include<stdio.h>
#include<malloc.h>
unsigned short maxim(unsigned short A[100])
{
unsigned short max = 0;
for (unsigned short i = 0; i<100; ++i)
if (A[i] > max)
max = A[i];
return max;
}
void main()
{
FILE *pFile = fopen("test.txt", "r");
unsigned short nrRows, nrColomns;
/* If empty exit */
if (pFile == NULL)
return;
fscanf(pFile, "%d", &nrRows);
fscanf(pFile, "%d", &nrColomns);
/* Memory Allocation */
int** V = (int**)malloc(nrRows * sizeof(int*)); /* Number of lines */
for (unsigned short i = 0; i < nrRows; ++i)
V[i] = (int*)malloc(nrColomns * sizeof(int)); /* Number of colomns */
/* Read the elements */
for (unsigned short i = 0; i < nrRows; ++i)
for (unsigned short j = 0; j < nrColomns; ++j)
fscanf(pFile, "%d", &V[i][j]);
/* Find max + array */
unsigned short A[100] = { '\0' }; unsigned short max = 0;
for (unsigned short i = 0; i < nrRows; ++i)
for (unsigned short j = 0; j < nrColomns; ++j)
{
/* How many times each value between [0 and 100) is found inside the matrix */
A[V[i][j]]++;
/* Find the biggest element */
if (V[i][j] > max)
max = V[i][j];
}
/* Memory Reallocation */
unsigned short maxA = maxim(A); unsigned short ok = 0;
if (maxA > nrColomns){
nrColomns = maxA;
ok++;
}
if (max + 1 > nrRows){
nrRows = max + 1;
ok++;
}
//if (ok != 0)
//{
*V = realloc(*V, nrRows * sizeof(int*));
for (unsigned short i = 0; i < nrRows; i++)
V[i] = (int*)realloc(V, nrColomns * sizeof(int));
//}
/* Rearrange Values */
unsigned short bool = 1;
while (bool != 0)
{
bool = 0;
for (unsigned short i = 0; i < nrRows; ++i)
{
for (unsigned short j = 0; j < nrColomns; ++j)
{
if (V[i][j] != i)
{
/* Swap elements */
unsigned short k = 0;
while (k < nrColomns)
{
if (V[V[i][j]][k] != V[i][j])
{
bool = 1;
/* Do the swapping */
int swap = V[V[i][j]][k];
V[V[i][j]][k] = V[i][j];
V[i][j] = swap;
break;
}
else k++;
}
}
}
}
}
/* Extra Reallocation */
if (maxA < nrColomns)
{
nrColomns = maxA;
for (unsigned short i = 0; i < nrRows; ++i)
V[i] = (int*)realloc(V, nrColomns * sizeof(int));
}
/* Print Result into file */
pFile = fopen("out.txt", "w");
fprintf(pFile, "%d %d \n", nrRows, nrColomns);
for (unsigned short i = 0; i < nrRows; ++i)
{
for (unsigned short j = 0; j < nrColomns; ++j)
fprintf(pFile, "%d ", V[i][j]);
fprintf(pFile, "\n");
}
fclose(pFile);
_getch();
/* Memory Deallocation */
for (unsigned short i = 0; i < nrRows; ++i)
free(V[i]);
free(V);
}
It's just wierd... I've lost enough hours on this problem.
Example of test.txt
4 3 1 2 2 0 0 0 1 1 3 5 3 2

I always hated realloc. If you are ok to avoid it, here's what I suggest :
Some points about your code, regardless of the problem :
in C it is better to declare all the variables at the start of any function. If possible, never declare a variable in middle of the code.
You can declare variable inside for block though. However it doesn't work in all version of C. Depends on the compiler.
Unless you will deploy this code on some device with really limited memory, you don't necessary have to use unsigned short. Classic integers would do.
It is recommended to check if every malloc went well. And if not, to do the necessary actions to avoid crash.
Code :
#include <stdio.h>
#include <stdlib.h>
int min(int a, int b) {
return (a < b) ? a : b;
}
void updateDimensions(int*** currentArray, unsigned short currentRowsNb, unsgined short currentColumnsNb, unsigned short newRowsNb, unsigned short newColumnsNb) {
int i;
int j;
int error;
int** res;
if(*currentArray != NULL && (newRowsNb != currentRowsNb || newColumnsNb != currentColumnsNb)) {
error = 0;
/* Memory allocation */
res = (int**)malloc(newRowsNb* sizeof(int*));
if(res != NULL) {
for(i=0 ; i < newRowsNb; i++) {
res[i] = (int*)malloc(newColumnsNb* sizeof(int));
if(res[i] == NULL) {
error = 1;
fprintf(stderr, "allocation error"); // Optional
while(--i >= 0)
free(res[i]);
free(res);
}
}
} else {
fprintf(stderr, "Allocation error);
error = 1;
}
/* End of memory allocation */
if(!error) {
/* Copy of the array */
for(i=0 ; i < min(currentRowsNb, newRowsNb) ; i++)
for(j=0 ; j < min(currentColumnsNb, newColumnsNb) ; j++)
res[i][j] = (*currentArray)[i][j];
/* End of copy */
/* Free current array */
for(i=0 ; i < currentNrRows ; i++)
free((*currentArray)[i]);
free(*currentArray);
/* End of free */
*currentArray = res; // Assign new array to current one.
}
}
}
unsigned short maxim(unsigned short A[100]) {
unsigned short max = 0;
unsigned short i;
for(i = 0 ; i < 100 ; i++)
if(A[i] > max)
max = A[i];
return max;
}
void main() {
/* Variable declaration */
unsigned short i;
unsigned short j;
unsigned short k;
unsigned short ok;
unsigned short max;
unsigned short maxA;
unsigned short nrRows;
unsigned short my_bool;
unsigned short nrColomns;
unsigned short A[100];
int swap;
int newNrRows;
int newNrColumns;
int tempInt;
int **V;
FILE *pFile;
/* Variable initialization */
pFile = fopen("test.txt", "r");
if(pFile == NULL)
return;
fscanf(pFile, "%d", &nrRows);
fscanf(pFile, "%d", &nrColomns);
max = 0;
my_bool = 1;
for(i=0 ; i < 100 ; i++)
A[i] = '\0';
/* Memory Allocation */
V = (int**)malloc(nrRows * sizeof(int*)); /* Number of lines */
if(V == NULL) {
fprintf(stderr, "Allocation error"); // Writes in the error output (optional)
return;
}
for (i = 0; i < nrRows; ++i)
V[i] = (int*)malloc(nrColomns * sizeof(int)); /* Number of colomns */
/* If allocation error */
if(v[i] == NULL) {
fprintf(stderr, "Allocation error"); // Optional
/* The following is mandatory */
while(--i > 0) { // Free all cell already allocated
free(A[i]);
}
free(A);
return;
}
}
/* End of memory allocation */
/* Read the elements */
for (i = 0; i < nrRows; ++i)
for (j = 0; j < nrColomns; ++j)
fscanf(pFile, "%d", &V[i][j]); // That assume you only have digit (0 to 9) in your file.
/* If you have a delimiter between numbers (here i'll take ';' as example, use this */
fscanf(pFile, "%[^;]%*d", &v[i][j]);
/* If you have many delimiters (here ';', ' ' and '\n' as example) */
fscanf(pFile, "%[^;\n ]%*d", &v[i][j]);
/* End of reading
/* Find max + array */
for (i = 0; i < nrRows; ++i)
for (j = 0; j < nrColumns; ++j) {
/* How many times each value between [0 and 100) is found inside the matrix */
A[V[i][j]]++;
/* Find the biggest element */
if (V[i][j] > max)
max = V[i][j];
}
/* Memory Reallocation */
maxA = maxim(A);
if (maxA > nrColomns) {
newNrColumns = maxA;
ok++;
}
if (max + 1 > nrRows) {
newNrColumns = max + 1;
ok++;
}
if (ok != 0) {
updateDimensions(&V, nrRows, nrColumns, newNrRows, newNrColumns);
nrRows = newNrRows;
nrColumns = newNrColumns;
}
/* Rearrange Values */
while (my_bool != 0) {
my_bool = 0;
for (i = 0; i < nrRows; ++i) {
for (j = 0; j < nrColomns; ++j) {
if (V[i][j] != i) {
/* Swap elements */
k = 0;
while (k < nrColomns) {
if (V[V[i][j]][k] != V[i][j]) {
my_bool = 1;
/* Do the swapping */
swap = V[V[i][j]][k];
V[V[i][j]][k] = V[i][j];
V[i][j] = swap;
break;
} else {
k++;
}
}
}
}
}
}
/* Extra Reallocation */
if (maxA < nrColomns) {
newNrColumns = maxA;
updateDimension(&V, nrRows, nrColumns, newNrRows, newNrColumns);
}
/* Print Result into file */
fclose(pFile);
pFile = fopen("out.txt", "w");
if(pFile == NULL) {
fprintf(stderr, "Error while openning file");
} else {
fprintf(pFile, "%d %d \n", nrRows, nrColomns);
for (unsigned short i = 0; i < nrRows; ++i) {
for (unsigned short j = 0; j < nrColomns; ++j)
fprintf(pFile, "%d ", V[i][j]);
fprintf(pFile, "\n");
}
fclose(pFile);
}
_getch();
/* Memory Deallocation */
for (i = 0; i < nrRows; ++i)
free(V[i]);
free(V);
}
NB : I did not try to compile this, it might have errors (especially on things like : (*currentArray)[i][j] ). Also, sorry for bad English ^^'

Related

The pointer variables overflows when they store integers larger than 1024 and some adresses seem to be locked.in C

How do I get to write to 2D pointers where I have pnumber[2%4][2%4] and how can I get pnumber with more than 3 ciphers to be displayed?
I'm making a program to write pascals triangle in C.
When the pointer pnumbers[i][j] have both i and j = 2 mod 4, except for when i and j = 2, then my program won't write to the address and give the error message:
pascals triangle: malloc.c:2406: sysmalloc: Assertion '{old_top == initial_top (av) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
Aborted.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int factorial(int p) {
if (p>=1) {
return p*factorial(p-1);
}
else {
return 1;
}
}
int NchooseM(int n, int m) {
return factorial(n)/(factorial(n-m)*factorial(m));
}
int main() {
int n =7;
int x = n-2;
int i, j, k;
/*
printf("How many rows of Pascals triangle do you want to write?\n");
scanf("%d", &n);
*/
int **pnumbers;
pnumbers = (int **) malloc(n *sizeof(int *));
/* Allocate memory for storing the individual elements in a row */
for (i = 0; i < n; i++) {
pnumbers[i] = (int *) malloc(i * sizeof(int));
}
pnumbers[0][1] = 1;
/* Calculating the value of pnumbers[k][l] */
for (i = 0; i < n; i++) {
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
/*
if (!(i % 4 == 2 && i != 2))
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
} else if (i > 2) {
for (j = 0; j <= i-1; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
}
*/
}
/* Writing out the triangle */
for (i = 0; i < n; i++) {
for (k = 0; k <= x; k++){
printf(" ");
}
for (j = 0; j <= i; j++) {
printf("%d ", pnumbers[i][j]);
}
x = x-1;
printf("\n");
}
for (i = 0; i < n; i++) {
free(pnumbers[i]);
}
free(pnumbers);
return 0;
}
When I avoid writing to these addresses and just print them out I get some seemingly random integer at these memory addresses.
Also when avoid these addresses and just print out so many rows that I get some spots with a higher integer with more than 3 siphers, it seems to overflow - and I don't see the logic behind it.
The result of running the second code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int factorial(int p) {
if (p>=1) {
return p*factorial(p-1);
}
else {
return 1;
}
}
int NchooseM(int n, int m) {
return factorial(n)/(factorial(n-m)*factorial(m));
}
int main() {
int n =20;
int x = n-2;
int i, j, k;
/*
printf("How many rows of Pascals triangle do you want to write?\n");
scanf("%d", &n);
*/
int **pnumbers;
pnumbers = (int **) malloc(n *sizeof(int *));
/* Allocate memory for storing the individual elements in a row */
for (i = 0; i < n; i++) {
pnumbers[i] = (int *) malloc(i * sizeof(int));
}
pnumbers[0][1] = 1;
/* Calculating the value of pnumbers[k][l] */
for (i = 0; i < n; i++) {
/*
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
*/
if (!(i % 4 == 2 && i != 2))
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
} else if (i > 2) {
for (j = 0; j <= i-1; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
}
}
/* Writing out the triangle */
for (i = 0; i < n; i++) {
for (k = 0; k <= x; k++){
printf(" ");
}
for (j = 0; j <= i; j++) {
printf("%d ", pnumbers[i][j]);
}
x = x-1;
printf("\n");
}
for (i = 0; i < n; i++) {
free(pnumbers[i]);
}
free(pnumbers);
return 0;
}
But row number 13 is still quite messed up.
Code is experiencing int overflow and thus undefined behavior (UB).
With 32-bit int and int factorial(int p), p > 12 oveflows the int range.
Code could use a wider integer type (long long works up to p==20), but improvements can be made at NchooseM() to avoid overflow for higher values.
Something like the below. Works up to int n = 30;
int NchooseM(int n, int m) {
// return factorial(n)/(factorial(n-m)*factorial(m));
int nm = 1;
int den = 1;
for (int i = m+1; i <= n; i++) {
assert(INT_MAX/i >= nm);
nm *= i;
assert(nm % den == 0);
nm /= den++;
}
return nm;
}
Tried unsigned long long and works up to int n = 62;
Edit: Another bug:
I "fixed" by initializing all to 1, yet I suspect something remains amiss in /* Calculating the value of pnumbers[k][l] */ for (i = 0; i < n; i++) { code.
pnumbers[i] = malloc((i + 1) * sizeof pnumbers[i][0]);
for (int j = 0; j < i + 1; j++) {
pnumbers[i][j] = 1;
}
Aside: rather than pnumbers[i] = (int *) malloc((i+1) * sizeof(int));, consider below with no unneeded cast nor trying to match the right type.
pnumbers[i] = malloc(sizeof pnumbers[i][0] * (i+1));

Counting Sort displays a weird behavior

I have implemented a Counting Sort in an assignment given to us by a teacher but sometimes it doesn't work for large arrays.
Here is the code:
void countingSort(int *t, int n) {
int min = findMin(t, n);
int max = findMax(t, n);
int range = max - min + 1;
int *count, *output;
int i;
count = (int *)malloc(range * sizeof(int));
output = (int *)malloc(n * sizeof(int));
for (i = 0; i < range; i++) {
count[i] = 0;
}
for (i = 0; i < n; i++) {
count[t[i] - min]++;
}
for (i = 1; i < range; i++) {
count[i] += count[i - 1];
}
for (i = n - 1; i >= 0; i--) {
output[count[t[i] - min] - 1] = t[i];
count[t[i] - min]--;
}
for (i = 0; i < n; i++) {
t[i] = output[i];
}
}
What's wrong with my code?
Your code seems to work for small values of range, but might fail if min and max are too far apart, causing the computation of range to overflow the range of int and malloc() to fail.
You should check for overflow in range and check memory allocation success. Note too that calloc() is more appropriate than malloc() for the count array. Finally, you must free the allocated arrays.
Here is a modified version:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
int findMax(const int *t, int n) {
int max = INT_MIN;
while (n-- > 0) {
if (max < *t) max = *t;
t++;
}
return max;
}
int findMin(const int *t, int n) {
int min = INT_MAX;
while (n-- > 0) {
if (min > *t) min = *t;
t++;
}
return min;
}
int countingSort(int *t, int n) {
int min, max, range, i;
int *count, *output;
if (n <= 0)
return 0;
min = findMin(t, n);
max = findMax(t, n);
if (min < 0 && max >= 0 && (unsigned)max + (unsigned)(-min) >= INT_MAX) {
fprintf(stderr, "countingSort: value range too large: %d..%d\n", min, max);
return -1;
}
range = max - min + 1;
if ((count = (int *)calloc(range, sizeof(int))) == NULL) {
fprintf(stderr, "countingSort: cannot allocate %d element count array\n", range);
return -1;
}
if ((output = (int *)malloc(n * sizeof(int))) == NULL) {
fprintf(stderr, "countingSort: cannot allocate %d element output array\n", n);
free(count);
return -1;
}
for (i = 0; i < n; i++) {
count[t[i] - min]++;
}
for (i = 1; i < range; i++) {
count[i] += count[i - 1];
}
for (i = n; i-- > 0;) {
output[count[t[i] - min] - 1] = t[i];
count[t[i] - min]--;
}
for (i = 0; i < n; i++) {
t[i] = output[i];
}
free(count);
free(output);
return 0;
}
You can avoid the cumbersome and potentially inefficient downward loop by replacing the second and third for loops with this:
/* compute the first index for each value */
int index = 0;
for (i = 0; i < range; i++) {
incr = count[i];
count[i] = index;
index += incr;
}
/* copy each value at the corresponding index and update it */
for (i = 0; i < n; i++) {
output[count[t[i] - min]++] = t[i];
}

Segmentation Fault:11 Error messages in C Terminal

While compiling in the terminal I keep getting the error Segmentation Fault: 11. The goal is to make dark circles on a picture of a boarder, ect with command. My reasoning that it isn't working if because of my File IO. I did it without the in & out FILE types and changed the two functions that are called in pgmUtility to not call in files and the program ran smoothly. So I'm assuming I need to have help focusing on the issues I have with my file IO.
Command used:
$ ./a.out -c 470 355 100 < balloons.ascii.pgm > TestImages/balloons_c100_4.pgm
It uses main.c program that relates to pgmUtility.c
This is Main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "pgmUtility.h"
#define ROWS 4
#define COLS 100
void usage(void)
{
printf("Usage\n");
printf(" -h Help Dialog\n");
printf(" -e edgeWidth < OldImageFile > NewImageFile\n");
printf(" -c centerRow centerCol radius < OldImageFile > NewImageFile\n");
printf(" -e edgeWidth -c radius centerRow centerCol < OldImageFile > NewImageFile\n");
exit (8);
}
int main(int argc, char * argv[]) {
FILE *fp;
FILE *out;
int i, j;
int flag1 = 0; //-e switch (edge draw)
int flag2 = 0; //-c switch (circle draw)
int numRows, numCols, centerRow, centerCol, radius, edgeWidth;
char originalImage[100], newImageFile[100];
char **header = (char**) malloc (sizeof(char*)*4);
int **pixels;
//command line argument parsing
//turn flag switches on or off
if(argc < 3)
usage();
if(argc > 7)
usage();
for(i = 1; i < argc; i++) {
if(strncmp(argv[i], "-e", 2) == 0) {
//set flag on
//get edge with values)
if(atoi(argv[i+1]) == 0) {
usage();
}
edgeWidth = atoi(argv[i+1]);
if(argv[i+2] != NULL) {
if(atoi(argv[i+2]) != 0) {
usage();
}
}
flag1 = 1;
}
if(strncmp(argv[i], "-c", 2) == 0) {
//set flag on
//get radius and center values
if(atoi(argv[i+1]) == 0) {
usage();
}
centerRow = atoi(argv[i+1]);
centerCol = atoi(argv[i+2]);
radius = atoi(argv[i+3]);
flag2 = 1;
strcpy(originalImage, argv[5]);
strcpy(newImageFile, argv[6]);
fp = fopen(originalImage, "r");
out = fopen(newImageFile, "w");
}
if(strncmp(argv[i], "-h", 2) == 0) {
usage();
}
}
//allocate memory for header array
header = (char **)malloc(ROWS * sizeof(char));
for(i = 0; i < ROWS; i++) {
for(j = 0; j < COLS; j++) {
header[i] = (char *)malloc(COLS * sizeof(char *));
}
}
//read pgm file
pixels = pgmRead(header, &numRows, &numCols, fp);
if(pixels == NULL)
usage();
switch(flag1) {
case 1 :
if(flag2 == 1) {
//execute circle draw and edge draw
pgmDrawCircle(pixels, numRows, numCols, centerRow, centerCol, radius, header);
pgmDrawEdge(pixels, numRows, numCols, edgeWidth, header);
}
else {
//execute only edge draw only
pgmDrawEdge(pixels, numRows, numCols, edgeWidth, header);
}
break;
case 0 :
if(flag2 == 1) {
//execute circle draw
pgmDrawCircle(pixels, numRows, numCols, centerRow, centerCol, radius, header);
}
break;
default :
usage();
break;
}
//write new pgm file
pgmWrite((const char **)header, (const int **)pixels, numRows, numCols, out);
//Garbage Collection
//Fix this
//free(pixels);
//free(header);
for(i = 0; i < numRows; i++) {
int *current= pixels[i];
free(current);
}
for(i = 0; i < ROWS; i++) {
char *current = header[i];
free(current);
}
return 0;
}
This is two functions from pgmUtility.c that I think may be the cause of the issue.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "pgmUtility.h"
#define ROWS 4
#define COLS 100
// Implement or define each function prototypes listed in pgmUtility.h file.
// NOTE: You can NOT change the input, output, and argument type of the functions in pgmUtility.h
// NOTE: You can NOT change the prototype (signature) of any functions listed in pgmUtility.h
int ** pgmRead( char **header, int *numRows, int *numCols, FILE *in ){
int r, c;
int **array;
for(r = 0; r < ROWS; r++) {
fgets(header[r], COLS, stdin);
if(header == NULL)
return NULL;
}
//sscanf parses the numRows and numCols
sscanf(header[ROWS - 2], "%d %d", numCols, numRows);
//read in pixel map
array = (int **)malloc(*numRows * sizeof(int *));
for(r = 0; r < *numRows; r++) {
array[r] = (int *)malloc(*numCols * sizeof(int));
}
for(r = 0; r < *numRows; r++) {
for(c = 0; c < *numCols; c++) {
fscanf(in, "%d", *(array + r) + c );
}
}
fclose(in);
return array;
}
int pgmWrite( const char **header, const int **pixels, int numRows, int numCols, FILE *out ){
//iterate straight through pixels
//setup with a loop to insert a new line every "numCols" and keep printing until "numRows + 1" is reached (as soon as numRows + 1 break loop)
int i, j;
for(i = 0; i < 4; i++){
//printf("%s", *header[i]);
fprintf(out, "%c", *header[i]);
}
//for(i = 0; i < 4; i++)
//fprintf(out, "*I=%d**%s**", i, header[i]);
for(j = 0; j < numRows; j++){
for(i = 0; i < numCols; i++)
fprintf(out, "%d ", pixels[i][j]);
fprintf(out, "\n");
}
fclose(out);
return 0;
}
You're not allocating the header arrays correctly. It should be:
header = malloc(ROWS * sizeof(char*));
for(i = 0; i < ROWS; i++) {
header[i] = malloc(COLS * sizeof(char));
}
You had the wrong types in the two sizeof calls.
You didn't need the inner j loop at all, you were repeatedly assigning to the same header[i].
And for C (but not C++) see: Do I cast the result of malloc?
Also, at the beginning of main() you have an extra allocation that you never use or free:
char **header = (char**) malloc (sizeof(char*)*4);
You should get rid of this.
It's not related to the error, but this is wrong:
if(header == NULL)
return NULL;
You should be testing header[r].
For clarity, I recommend rewriting:
fscanf(in, "%d", *(array + r) + c );
as:
fscanf(in, "%d", &array[r][c]);
It appears (even after correcting the malloc call as correctly suggested), you are allocating header[i] COLS number of times.
header = malloc(ROWS * sizeof(char*));
for(i = 0; i < ROWS; i++) {
for(j = 0; j < COLS; j++) {
header[i] = malloc(COLS * sizeof(char)); // this happens COLS times
}
}
That will leave COLS number of each header[i] allocated. As I read your code, you need only allocate a single char array for each header[i]. To do this, you need to move header[i] = malloc(COLS * sizeof(char)); outside the for(j = 0; j < COLS; j++) loop:
header = malloc(ROWS * sizeof(char*));
for(i = 0; i < ROWS; i++) {
header[i] = malloc(COLS * sizeof(char));
}
You should also validate that header and each header[i] were successfully allocated.

Segmentation fault with a Sieve of Eratosthenes program

I'm trying to implement the sieve algorithm where it'll ask for the size of a list of consecutive numbers and print out the prime numbers in that list, but I'm getting a seg fault: 11 error.
This is my code:
#include <stdio.h>
#include <stdlib.h>
#define LIMIT 1000000 /*size of integers array*/
int main(void){
char n[LIMIT];
//Reads the size of integer array
printf("Size of array:\n");
if((fgets(n, LIMIT, stdin)) == NULL) {
fprintf(stderr, "Could not read from stdin\n");
exit(1);
}
unsigned long long int i,j;
int *primes;
int z = 1;
primes = malloc(sizeof(n));
for (i = 2; i < sizeof(n); i++){
primes[i] = 1; //setting every number in list to 1
}
for (i = 2; i < sizeof(n); i++){
if (primes[i]){
for (j = i; (i*j) < sizeof(n); j++){
primes[i * j] = 0; //remove multiples
}
}
}
for (i = 2; i < sizeof(n); i++){
if (primes[i]){
printf("%dth prime = %llu\n",z++,i);
}
}
free(primes);
return 0;
}
char n[LIMIT];
With the value of LIMIT being 1000000, that's a really big array (one million bytes). It would cause stack overflow. You need to dynamically allocate memory for it:
char *n = malloc(LIMIT);
Code is using n in a curious fashion. Suggest simply scanning the the integer n and using n to end the loops rather than sizeof(n).
#include <stdio.h>
#include <stdlib.h>
int main(void){
unsigned long n;
//Reads the size of integer array
buffer[30];
printf("Size of array:\n");
if((fgets(buffer, sizeof buffer, stdin)) == NULL) {
fprintf(stderr, "Could not read from stdin\n");
exit(1);
}
if (sscanf(buffer,"%lu", %n) != 1) {
fprintf(stderr, "Unable to covert to a number\n");
exit(1);
}
unsigned long i,j;
int *primes;
// int z = 1;
primes = malloc(n * sizeof *primes);
for (i = 2; i < n; i++){
primes[i] = 1; //setting every number in list to 1
}
for (i = 2; i < n; i++){
if (primes[i]) {
for (j = i; (i*j) < n; j++){
primes[i * j] = 0; //remove multiples
}
}
}
for (i = 2; i < n; i++){
if (primes[i]){
printf("%dth prime = %llu\n",z++,i);
}
}
free(primes);
return 0;
}

(C) Radix Sort array from text file

I am attempting to get this queue-based radix sort to work, but I can't seem to figure out what's wrong with it. It uses a text file as the input medium and throws tons of errors when I try to compile it and run it with the text file.
Any advice would be helpful at this point.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
#define SHOWPASS
//Compiled Using GNU GCC Compiler
void radixsort(int *a[], int n)
{
int i, b[MAX], m = *a[0], exp = 1;
for (i = 0; i < n; i++)
{
if (*a[i] > m)
m = a[i];
}
while (m / exp > 0)
{
int queue[10] =
{ 0 };
for (i = 0; i < n; i++)
queue[*a[i] / exp % 10]++;
for (i = 1; i < 10; i++)
queue[i] += queue[i - 1];
for (i = n - 1; i >= 0; i--)
b[--queue[*a[i] / exp % 10]] = *a[i];
for (i = 0; i < n; i++)
*a[i] = b[i];
exp *= 10;
#ifdef SHOWPASS
printf("\nPASS : ");
radixsort(a, n);
#endif
}
}
int main( int argc, char *argv[] )
{
if ( argc != 3 )
{
printf("Need two input parameters in the following order: \n 1. Input file path \n 2. Number of elements in file\n");
return 0;
}
int num_elements = atoi(argv[2]);
int *input_arr = (int*) calloc (num_elements, sizeof(int));
int i;
FILE *fin; //File pointer to read input file
fin = fopen(argv[1], "r"); //Initialize file pointer
for(i=0; i<num_elements; i++)
{
fscanf(fin, "%d", &(input_arr[0]));
}
radixsort(input_arr[0], i);
printf ( "\nArray before sorting: \n") ;
for ( i = 0 ; i < num_elements ; i++ )
printf ( "%d\t", input_arr[0] ) ;
printf ( "\n\n");
return 0;enter code here
}
There are plenty of errors in your code. Firstly, the way you are taking input is incorrect.
fscanf(fin, "%d", &(input_arr[0]));
While taking input, the array input_arr is filled with a single input value at input_arr[0]. The rest of the input is over-written at input_arr[0].
Replace it with, fscanf(fin, "%d", &(input_arr[i]));.
Even you are displaying output in incorrect way.After sorting, the same output will be displayed num_elements times because of the following incorrect statement:
printf ( "%d\t", input_arr[0] ) ;
Again replace the above statement with printf ( "%d\t", input_arr[i] ).
As an impact of following incorrect statement,
fscanf(fin, "%d", &(input_arr[i])); ,
your program experiences a Segmentation fault, since in function radixsort, you are iterating from 0 to n-1(Number of elements).
for (i = 0; i < n; i++)
{
if (*a[i] > m)
m = a[i];
}
As only a[0] is filled with input value and rest of the array(from a[1] to a[n-1]) contains a garbage value, you will get a runtime error while executing your code.
There are lot of other bugs too, which i had fixed. This is the perfect running code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
// #define SHOWPASS
// Compiled Using GNU GCC Compiler
void radixsort(int a[], int n)
{
int i, b[MAX], m = a[0], exp = 1;
for (i = 0; i < n; i++)
{
if (a[i] > m)
m = a[i];
}
while (m / exp > 0)
{
int queue[10] = { 0 };
for (i = 0; i < n; i++)
queue[a[i] / exp % 10]++;
for (i = 1; i < 10; i++)
queue[i] += queue[i - 1];
for (i = n - 1; i >= 0; i--)
b[--queue[a[i] / exp % 10]] = a[i];
for (i = 0; i < n; i++)
a[i] = b[i];
exp *= 10;
#ifdef SHOWPASS
printf("\nPASS : ");
radixsort(a, n);
#endif
}
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
printf
("Need two input parameters in the following order: \n 1. Input file path \n 2. Number of elements in file\n");
return 0;
}
int num_elements = atoi(argv[2]);
int *input_arr = (int *)calloc(num_elements, sizeof(int));
int i;
FILE *fin; // File pointer to read input file
fin = fopen(argv[1], "r"); // Initialize file pointer
for (i = 0; i < num_elements; i++)
{
fscanf(fin, "%d", &(input_arr[i]));
}
radixsort(input_arr, i);
printf("\nArray before sorting: \n");
for (i = 0; i < num_elements; i++)
printf("%d\t", input_arr[i]);
printf("\n\n");
return 0;
}

Resources