c sorting large struct array and printing to screen - c

I'm having trouble sorting a struct array and then printing it to screen. When I run the code in Visual Studio 2012, it doesn't print AT ALL. I've spent hours figuring it out, and debugging mode is very buggy. I really need to know why it isn't doing what I tell it to do.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
struct RandStruct
{
int year;
char string[31];
int frequency;
};
struct RandStruct randArray[150000];
int main(void)
{
int i, j;
for (i = 0; i < 150000; i++)
{
randArray[i].year = 150000 - i;
strcpy(randArray[i].string, "test");
randArray[i].frequency = i;
}
for (i = 1; i < 150000; i++)
{
for (j = 0; j < 150000 - i; j++)
{
if (randArray[j].year > randArray[j+1].year)
{
struct RandStruct temp = randArray[j];
randArray[j] = randArray[j+1];
randArray[j+1] = temp;
}
}
}
for (i = 0; i < 150000; i++)
{
printf("%d,%s,%d\n", randArray[i].year, randArray[i].string, randArray[i].frequency);
}
return 0;
}

For sorting, you should use the qsort function instead of reinventing the wheel.
#include <stdlib.h>
int my_compar(const void *a, const void *b) {
const struct RandStruct *aa = a;
const struct RandStruct *bb = b;
if(aa->year < bb->year) return -1;
if(aa->year == bb->year) return 0;
return 1;
}
int main(void) {
... other stuff ...
size_t size = sizeof(struct RandStruct);
qsort(randArray, sizeof(randArray)/size, size, my_compar);
}

Related

problem passing dynamic array via function c

I have this kind of code
typedef struct {
int x;
int y;
} Test;
Test* getTest(int *length) {
Test *toReturn = malloc(sizeof(Test));
// Some operations with realloc
return toReturn;
}
void printTest(Test *arrTest, int length) {
for(int i = 0; i < length; i++) {
// Some operations
}
}
int main() {
int testlength = 0;
Test *myTest = getTest(&testlength);
printTest(myTest, testLength) // Gives random numbers
}
Don't know why it gives random numbers, when I'm in the main tho (the whole code) it does not give these kinds of errors
Made minor changes to the code, see below:
#include <stdio.h>
typedef struct {
int x;
int y;
} Test;
Test* getTest(int *length) {
Test *toReturn = (Test *)malloc(sizeof(Test));
// Some operations with realloc
return toReturn;
}
void printTest(Test *arrTest, int length) {
printf("%d ", length);
for(int i = 0; i < length; i++) {
// Some operations
}
}
int main() {
int tlen = 0;
Test *myTest = getTest(&tlen);
printTest(myTest, tlen); // Gives random numbers
printf("....Exit....");
return 0;
}

C typedef: pointer to struct

For my personal entertainment I am learning C. I am trying to write a matrix calculation header. I have a function to show the matrix, rmat_show(rmatrix *r), which should printf the entire matrix. However, it seems that my data type rmatrix is not passed well to this function.
rmat.h:
// Matrix struct, m x n matrix. Pointer *value points to the contents.
struct srmatrix {
int m,n;
float *value;
};
typedef struct srmatrix rmatrix;
// Show the matrix
void rmat_show(rmatrix* r) {
int i, j;
printf("\nshow\n");
printf("[%dx%d]\n",r->m,r->n);
for (i = 0; i < r->m; i++) {
for (j = 0; j < r->m; j++) {
printf("%d\t",value[(j-1)*r->m+i-1]);
}
printf("\n");
}
}
And I have this as main file:
#include "rmat.h"
int main(int argc, char **argv){
float val[] = {0.1};
rmatrix *r = malloc(sizeof(rmatrix));
r->n = 1;
r->m = 1;
r->value = val;
rmat_show(r);
return 0;
}
After rmat_show I attempt to kill te matrix with another function. It yields the same error, which is: 'incompatible type for argument 1 of 'rmat_show' expected 'rmatrix' but argument was of type 'struct rmatrix *''. I have tried searching 'pointer to typedef' and similar terms, without result. I believe the typedef declaration is not carried over to the function defenition. I use msys and mingw on windows 7.
Thanks for the help.
Edit: added the typedef line I miscopied.
Seems you are using the same loop variable twice
for (i = 0; i < r->m; i++) {
for (i = 0; i < r->m; i++)
you probably meant
for (i = 0; i < r->m; i++) {
for (j = 0; j < r->n; j++)
EDIT:
you may want to use the right name of the struct as well
struct srmatrix
not
rmatrix *r = malloc(sizeof(rmatrix));
but
struct srmatrix *r = malloc(sizeof(struct srmatrix));
whether you include struct or not depends on your compiler version C/C++
This
struct srmatrix {
int m,n;
float *value;
};
...
void rmat_show(rmatrix* r)
{
...
for (i = 0; i < r->m; i++)
{
for (i = 0; i < r->m; i++)
{
printf("%d\t", value[(n-1)*r->m+m-1]);
}
printf("\n");
}
...
should be this
rmat.h:
#ifndef RMAT_H
#define RMAT_H
typedef struct rmatrix_s {
size_t m, n; /* There is no need to define dimension as signed. */
float * value;
} rmatrix_t;
void rmat_show(rmatrix_t * r);
#endif
rmat.c:
...
#include "rmat.h"
void rmat_show(rmatrix_t * r)
{
...
for (size_t j = 0; j < r->n; j++)
{
for (size_t i = 0; i < r->m; i++)
{
printf("%d\t", value[j*r->m + i]);
}
printf("\n");
}
The main would then have:
...
#include "rmat.h"
int main(int argc, char **argv)
{
...
rmatrix_t * r = malloc(sizeof(*r));
...
To compile this do:
gcc -g -Wall -Wextra -o main main.c rmat.c

Returning merged arrays from function in C

I have the following code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct _item {
int v, w;
} item;
void printItems(item *t, int n) {
int i;
for(i= 0; i < n; i++)
printf("%4i",t[i].v);
printf("\n");
}
item * newItemSet(int n) {
int i;
item *t = (item*)malloc(sizeof(item));
for (i = 0; i < n; i++){
(t+i)->v = rand()%100;
(t+i)->w = rand()%100;
}
return t;
}
item * mer(item*a, int n, item*b, int m) {
int size = m+n;
item*q = (item*)malloc(sizeof(item)*size);
int i, c;
c = 0;
printf("a----\n");
printItems(a,n);
printf("b----\n");
printItems(b,m);
for(i = 0; i<n; i++) {
q[c] = a[i];
c++;
}
for(i = 0; i<m; i++) {
q[c] = b[i];
c++;
}
printItems(q,size);
return q;
}
int main(void) {
srand(time(NULL));
item * a = newItemSet(6);
item *b = newItemSet(6);
item *c = mer(a,6,b,6);
printItems(c,12);
return 0;
}
At every execution, the first part of c is correct, up to the last two elements of b. What did I miss?
The allocation for newItemSet does not appear correct. It should be:
item *t = malloc(sizeof(item) * n);
item *t = (item*)malloc(sizeof(item));
Should be:
item *t = malloc(n * sizeof(item));
You are allocating space for n items, not one item. Also, there is no need to cast the return value of malloc and it can hide errors.

writing to an array of structs

I have the following code
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef struct Example
{
uint16_t a;
uint16_t b;
} ExampleStruct;
void derp(struct Example * bar[], uint8_t i)
{
uint8_t c;
for(c = 0; c < i; ++c)
{
bar[c]->a = 1;
bar[c]->b = 2;
}
}
int main()
{
struct Example * foo;
uint8_t i = 3;
foo = malloc(i*sizeof(ExampleStruct));
derp(&foo, i);
free(foo);
return 0;
}
I get segfaults and all debuggers tell me that code stopped working due to
bar[c]->a = 1;
I tried to rearrange this into all of the following
(*bar)[c]->a = 1;
(*bar[c])->a = 1;
bar[c].a = 1;
(*bar)[c].a = 1;
and with no success. What am I doing wrong? I don't understand why is this failing, and I don't understand why the addresses of bar[0], bar[1] and bar[2] are so far away from each other, when each just takes 2 bytes.
There's no need to pass &foo. Keep it simple:
// In a function declaration, it's (almost) always a pointer, not an array.
// "struct Example bar[]" means *exactly* the same thing in this context.
void init(struct Example * bar, int n) {
int i;
for (i = 0; i < n; ++i) {
bar[i].a = 1;
bar[i].b = 2;
}
}
int main() {
int n = 3;
struct Example * foo = malloc(n*sizeof(struct Example));
init(foo, n); // passes the address of the array - &a[0] - to init
printf("The second element is {%u, %u}\n", foo[1].a, foo[1].b);
free(foo);
return 0;
}
output:
The second element is {1, 2}
Some changes were required since you were trying to pass array of objects:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
typedef struct Example
{
uint16_t a;
uint16_t b;
} ExampleStruct;
void derp(struct Example * bar[], uint8_t i)
{
uint8_t c;
for(c = 0; c < i; ++c)
{
bar[c]->a = 1;
bar[c]->b = 2;
}
}
int main()
{
struct Example * foo[3];
uint8_t i = 3, c;
for(i = 0; i < 3; i++)
foo[i] = malloc(sizeof(ExampleStruct));
derp(foo, i);
for(c = 0; c < i; ++c)
{
printf("\n%" PRIu16 " %" PRIu16 ,foo[c]->a,foo[c]->b);
}
for(i = 0; i < 3; i++)
free(foo[i]);
return 0;
}
struct Example * foo; can hold a single pointer to an object of type struct Example. While struct Example * bar[] can hold an array of pointers to objects of type struct Example.
In your original program, this will seg fault when c is greater than 0 since you did not allocate any pointers to an object of type struct Example.
bar[c]->a = 1;
bar[c]->b = 2;
For static objects:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
typedef struct Example
{
uint16_t a;
uint16_t b;
} ExampleStruct;
void derp(struct Example bar[], uint8_t i)
{
uint8_t c;
for(c = 0; c < i; ++c)
{
bar[c].a = 1;
bar[c].b = 2;
}
}
int main()
{
struct Example foo[3];
uint8_t i = 3, c;
derp(foo, i);
for(c = 0; c < i; ++c)
{
printf("\n%" PRIu16 " %" PRIu16 ,foo[c].a,foo[c].b); //accessing in main
}
return 0;
}

EXC_BAD_ACCESS on pointer in linked list for radix sort

I'm trying to come up with a rudimentary radix sort (I've never actually seen one, so I'm sorry if mine is awful), but I am getting an EXC_BAD_ACCESS error on the line link = *(link.pointer);. My C skills aren't great, so hopefully someone can teach me what I'm doing wrong.
I'm using XCode and ARC is enabled.
Here is the code:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#define ARRAY_COUNT 10
#define MAX_VALUE 1000000
#define MODULO 10.0f
typedef enum
{
false,
true
} bool;
typedef struct linkedListStruct
{
int value;
struct linkedListStruct *pointer;
} LinkedList;
void radixSort(int *array);
bool arraySorted(int *array);
int * intArray(int minValue, int maxValue);
int main(int argc, const char * argv[])
{
int *sortingArray = intArray(0, MAX_VALUE);
radixSort(sortingArray);
printf("Array %s sorted", arraySorted(sortingArray) ? "" : "not");
return 0;
}
void radixSort(int *array)
{
int numberOfIterations = (int)ceilf(log(MAX_VALUE)/log(MODULO));
for(int n = 0; n < numberOfIterations; n++)
{
LinkedList *linkedListPointers[(int)MODULO] = {0};
int i = ARRAY_COUNT;
while(i--)
{
int location = (int)floor((array[i] % (int)powf(MODULO, n + 1))/powf(MODULO, n));
LinkedList link = { array[i], NULL };
link.pointer = linkedListPointers[location];
linkedListPointers[location] = &link;
}
int location = 0;
for(int pointerSelection = 0; pointerSelection < MODULO; pointerSelection++)
{
if(linkedListPointers[pointerSelection])
{
LinkedList link = { 0, linkedListPointers[pointerSelection] };
linkedListPointers[pointerSelection] = NULL;
while(link.pointer)
{
link = *(link.pointer);
array[location++] = link.value;
}
}
}
}
}
bool arraySorted(int *array)
{
int i = ARRAY_COUNT;
while(--i)if(array[i - 1] > array[i])break;
return !i;
}
int * intArray(int minValue, int maxValue)
{
int difference = maxValue - minValue;
int *array = (int *)malloc(sizeof(int) * ARRAY_COUNT);
int i;
for(i = 0; i < ARRAY_COUNT; i++)
{
array[i] = rand()%difference + minValue;
}
return array;
}
Also, if someone wants to suggest improvements to my sort, that would also be appreciated.
The problem came from how I was allocating the linked list. I changed
LinkedList link = { array[i], NULL };
link.pointer = linkedListPointers[location];
to
LinkedList *link = malloc(sizeof(LinkedList));
link->value = array[i];
link->pointer = linkedListPointers[location];
In the first example, the pointer to link remained the same through each loop iteration (I wasn't aware it would do that), so I needed to make the pointer point to a newly allocated memory chunk.
EDIT:
Changing that also had me change from
while(link.pointer)
{
link = *(link.pointer);
array[location++] = link.value;
}
to
while(linkPointer)
{
link = *linkPointer;
array[location++] = link.value;
linkPointer = link.pointer;
}

Resources