problem passing dynamic array via function c - 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;
}

Related

C, Segmentation fault while using dynamic array in struct

I'm trying to add new element to dynamic array in C (I know that I must free all memory. I will do it later), but I get this error every time:
But, what is strange, if I compile from terminal, like that, code works properly.
So, where is the error and how i can beat it?
Thank you!
All my code:
main.c
#include <stdio.h>
#include <stdlib.h>
typedef struct vector
{
int size;
int *array;
int alreadyIn;
}vector;
vector *vectorInit(int size)
{
vector *newVec = (vector *)malloc(sizeof(vector));
if(!newVec){printf("No memory!\n"); return NULL;}
newVec->size = size;
newVec->array = (int *)malloc(size * sizeof(int));
return newVec;
}
void allocNewMemory(vector *vect, int howMuch)
{
vect->array = (int *)realloc(vect->array ,(vect->size + howMuch) * sizeof(int));
vect->size += howMuch;
}
void pushBack(vector *vect, int number)
{
int howMuch = 5;
if(vect && vect->alreadyIn < vect->size)
{
vect->array[vect->alreadyIn] = number;
vect->alreadyIn++;
}
else
{
printf("Alloc new memory for %d elements...\n", howMuch);
allocNewMemory(vect, howMuch);
pushBack(vect, number);
}
}
void printVector(vector *vect)
{
for (int i = 0; i < vect->alreadyIn; i++)
{
printf("%d ", vect->array[i]);
}
printf("\n");
}
int main()
{
int startSize = 4;
vector * vec = vectorInit(startSize);
for (int i = 0; i < 6; i++)
{
pushBack(vec, i+1);
}
printVector(vec);
return 0;
}
You never initialize the alreadyIn member in the structure. That means its value will be indeterminate (and seemingly garbage or random).
You need to explicitly initialize it to zero:
vector *vectorInit(int size)
{
vector *newVec = malloc(sizeof(vector));
if(!newVec)
{
printf("No memory!\n");
return NULL;
}
newVec->size = size;
newVec->array = malloc(size * sizeof(int));
newVec->alreadyIn = 0; // Remember to set this to zero
return newVec;
}
This problem should have been easy to detect in the debugger.
Also note that I removed the casts from malloc. One should not cast the result of malloc, or really any function returning void *.

How do you make a FIFO array in C

I need an array with a limited size where I can push ints in.
Once the array is full the last one in the array needs to go out so there is a new spot in front so I can keep adding data. How can you do this in C?
this should be a reasonable implementation
#include <stdio.h>
#include <stdlib.h>
struct int_queue{
int *arr;
size_t size;
int len;
int first_elem;
};
void init_int_queue(struct int_queue *queue, size_t nelems)
{
queue->arr = malloc(nelems*sizeof(int));
queue->first_elem = 0;
queue->len = 0;
queue->size = nelems;
}
void destroy_int_queue(struct int_queue *queue)
{
free(queue->arr);
}
void push_int(struct int_queue *queue, int new_val)
{
queue->arr[(queue->first_elem + (queue->len)++) % queue->size] = new_val;
if (queue->len > queue->size){
queue->len--;
queue->first_elem++;
queue->first_elem %= queue->size;
}
}
int get_int(struct int_queue *queue, int index)
{
// note does not handle the case for index out of bounds
// wraps around for overflow
return queue->arr[(queue->first_elem + index) % queue->size];
}
void print_int_queue(struct int_queue *queue)
{
printf("[");
for(int i = 0; i < queue->len; ++i){
printf("%d", queue->arr[(queue->first_elem + i) % queue->size]);
if(i < queue->len - 1)
printf(", ");
}
printf("]\n");
}
int main(int argc, char *argv[])
{
struct int_queue queue;
init_int_queue(&queue, 100);
for(int i = 0; i < 150; ++i){
push_int(&queue, i);
}
print_int_queue(&queue);
destroy_int_queue(&queue);
return 0;
}
Not extensively tested but it's simply wrapping around the array everytime a new element is added, keeping track of the first element shifting if the length exceeds the size.

Hash table implementation bad access error

I was trying to make a hash table for my project but I keep getting bad access error. There is no mistake in syntax as compiler tells me. I think I have made a mistake in memory allocation but I can't see it. Any help is appreciated.
I get a bad access error in this loop:
hash_itself_p hash_table = (hash_itself_p)malloc(sizeof(hash_itself_t));
for (i = 0; i < 50; i++)
{
hash_table->data_id[i]->id = -1; // EXC_BAD_ACCESS here
}
And here is the all of the code:
#include <stdio.h>
#include <stdlib.h>
#define size 50
typedef struct hash_value
{
int id;
int data;
int key;
} hash_values_t[1], *hash_values;
typedef struct hash_itself
{
hash_values data_id[size];
} hash_itself_t[1], *hash_itself_p;
int hash_key(int n)
{
return ( n*n + 2*n ) % size;
}
int hash_id(int n)
{
return n % size;
}
void insert(hash_itself_p hash_table, int person)
{
int id;
int key;
key = hash_key(person);
id = hash_id(key);
if (hash_table->data_id[id]->id == -1)
{
hash_table->data_id[id]->id = id;
hash_table->data_id[id]->data = person;
}
else
{
int block = id;
while (hash_table->data_id[block%50]->id != -1)
{
block++;
if (block%50 == id) return;
}
hash_table->data_id[block]->id = id;
hash_table->data_id[block]->data = person;
}
}
void display(hash_itself_p hash_table)
{
int i;
for (i = 0; i < size; i++)
{
printf("id = %d, data = %d, key = %d \n", hash_table->data_id[i]->id, hash_table->data_id[i]->data, hash_table->data_id[i]->key);
}
}
int main()
{
int i;
hash_itself_p hash_table = (hash_itself_p)malloc(sizeof(hash_itself_t));
for (i = 0; i < 50; i++)
{
hash_table->data_id[i]->id = -1;
}
insert(hash_table, 30);
display(hash_table);
}
You've declared the data_id array in hash_itself as an array of pointers to hash_value structs. Since those pointers are not initialized, it accesses invalid memory.
I think you wanted to create an array of the structs directly, in which case you want:
typedef struct hash_itself
{
hash_values_t data_id[size];
}

c sorting large struct array and printing to screen

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);
}

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