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];
}
Related
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;
}
I have recently read a code but I have a doubt in code
toTs *now = try();
now->index = 30;
Where toTs is a struct and try() is a function with return type toTs*
*now being a pointer can keep address of label try() but as try() not being a structure variable now can't access it like struct and can never access it like now->index=30.
After compiling it shows segmentation fault.
I just want to ask is above code legitimate or not.
#include <stdio.h>
#include <unistd.h>
typedef struct toT {
int index;
} toTs;
toTs lst[3];
toTs *try() {
int i;
for (i = 0; i < 3; i++) {
toTs *current = &lst[i];
printf("%d\n", current->index);
if (current->index == 3) {
printf("test work");
return current;
}
}
}
int main() {
int i;
for (i = 0; i < 3; i++) {
lst[i].index = i;
}
for (i = 0; i < 3; i++) {
printf("test %d\n", lst[i].index);
}
toTs *now = try();
now->index = 30;
printf("current %d\n", now->index);
printf("current %d\n", lst[2].index);
}
now is a struct pointer that can point to struct variable but try() is not a struct variable nor array of data structure its a function
You need to always return a valid toTs* from try() for the code to work.
#include <stdio.h>
#include <unistd.h>
typedef struct toT {
int index;
} toTs;
toTs lst[4];
toTs *try() {
int i;
for (i = 0; i < 3; i++) {
toTs *current = &lst[i];
printf("%d\n", current->index);
if (current->index == 3) {
printf("test work");
return current;
}
}
return &lst[3]; // return a spare structure.
}
int main() {
int i;
for (i = 0; i < 3; i++) {
lst[i].index = i;
}
for (i = 0; i < 3; i++) {
printf("test %d\n", lst[i].index);
}
toTs *now = try();
now->index = 30;
printf("current %d\n", now->index);
for (i = 0; i < 4; i++) {
printf("Final %d\n", lst[i].index);
}
}
You're confusing function pointers with plain pointers in C. Function pointers go deeper : https://en.wikipedia.org/wiki/Function_pointer
This code is not particularly healthy.
Given the way lst is initialized, when you call try() it will reach the end of that function without a return statement.
The C Standard says that if you use the return value of a function, without actually returning a value, that's undefined behavior.
Im currently working on a project (for school, yes) in which i've spent quite a few hours trying to get it to work, but now i found myself with an error that i cant seem to solve, and so i came here looking for help. The following is the code that i think is necessary, not the full code.
typedef struct
{
int day, month, year;
} typeDate;
typedef struct
{
int number;
char name[20];
char lastname[20];
typeDate date_of_birth;
} typeCard;
typedef struct
{
int associate_number;
typeCard associates[MAX_ELEM];
} typeAssociation;
typeDate date;
typeCard card;
typeCard aux;
int get_data(typeAssociation association)
{
association.associate_number = 0;
int e, i;
FILE* read = fopen("associados.txt", "r");
for (i = 0; fscanf(read, "%s %s %d %d %d %d", card.name, card.lastname, &card.number,
&date.day, &date.month, &date.year)
!= EOF;
i++)
{
association.associate_number++;
card.date_of_birth = date;
association.associates[i] = card;
}
fclose(read);
printf("Sort list[1/2/3]?");
scanf("%d", &e);
if (e == 1)
{
ordenar_n(&associacao);
}
(...)
}
int sort_by_date(typeAssociation association)
{
int g, m, i;
for (i = 0; i < association.associate_number - 1; i++)
{
m = i;
for (g = i + 1; g < data.year; g++)
{
if (date.year[g] < date.year[m])
{
m = g;
}
if (date.year[g] == date.year[m])
{
if (date.month[g] < date.month[m])
{
m = g;
}
else if (date.month[g] == date.month[m])
{
if (date.day[g] < date.day[m])
{
m = g;
}
}
}
aux = association.associates[i];
association.associates[i] = association.associates[m];
association.associates[m] = aux;
}
}
}
on another file i have (after calling the file):
int main(void)
{
typeAssociation association;
get_data(association);
}
The error is in the function sort_by_date and this function is supposed to sort a list (given by associados.txt) by date (stored in the struct typeDate) (from newest member to the oldest). I think (correct me if I'm wrong) i have the general idea going, but not the code. Can anyone help me? (it's my first post so sorry for any mistakes).
My error is in the function sort_by_date.
You are passing typeAssociation by value. Your sort is not applying to the object passed in. Also, don't write your own sort. qsort is a library function.
int sort_by_date(typeAssociation *association)
{
qsort(association->associates, association->associate_number, sizeof(typeCard), compare_typeCard);
}
int compare_typeCard(const void *avoid, const void *bvoid)
{
typeCard *a = avoid;
typeCard *b = bvoid;
/* put your comparison code here */
}
And, you have the same pass-by-value mistake calling getAssociation.
You need to pass address of typeAssociation variable.
Also in your code, you are comparing array elements with some global variables which is wrong.
int sort_by_date(typeAssociation *association)
{
int g=0, m=0, i=0;
for (i = 0; i < association->associate_number - 2; i++)
{
m = i;
for (g = i + 1; g < association->associate_number; g++)
{
if (association->associates[g].date.year < association->associates[m].date.year)
{
m = g;
}
else if (association->associates[g].date.year == association->associates[m].date.year)
{
if (association->associates[g].date.month < association->associates[m].date.month)
{
m = g;
}
else if (association->associates[g].date.month == association->associates[m].date.month)
{
if (association->associates[g].date.day < association->associates[m].date.day)
{
m = g;
}
}
}
}
//No need to do it in i loop
if(i != m)
{
aux = association.associates[i];
association.associates[i] = association.associates[m];
association.associates[m] = aux;
}
}
return 0; //Need to return an int value.
}
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;
}
I have a simple structure called entry defined which contains name and age. Given an array of these structures, I want to sort the array based on age.
Below is my attempt at applying this, at the moment I can't even get this to compile. I think my pointer logic is incorrect in both the if statement comparison and the subsequent swapping of the pointers. I've tried various ways to do the same thing, but I'm not getting anywhere. I'm pretty new to C, and I'm still trying to get my head around pointers, so it's probably something basic I'm misunderstanding. Can anybody please explain what I'm doing wrong below?
Any help would be greatly appreciated.
#include <stdio.h>
struct entry {
char name[15];
int age;
};
void entrySort( struct entry *dict);
void entrySort( struct entry *dict){
int i,j; // counters
int ct = 4;
struct entry *tmp; // temporary holder
for( i = 0; i < ct; i++){
for( j = 0; j < ct; j++ ){
if ((*dict[i].age) > (*dict[j].age)){
tmp = (dict + i);
(dict+i) = (dict+j);
(dict+j) = tmp;
}
}
}
int main (void){
int ct = 4, i;
struct entry reg[4] =
{{ "John", 24 },
{ "Alan", 18 },
{ "Jim", 40 },
{ "Sarah",32 }};
entrySort(reg);
for( i = 0; i < ct; i++)
printf("name: %s. Age: %d\n", reg[i].name, reg[i].age);
return 0;
}
You pass an array of struct entry objects as a pointer: struct entry *dict, but you are treating it as it would be an array of pointers to struct entry objects: (*dict[i]).age.
(dict+i) is still just a pointer pointing to the memory where i+1. element is stored, i.e. &dict[i]. To actually access this element at index i, you need to use dereference operator: *(dict + i), which is equal to dict[i].
And also note that your swapping of elements at i and j is wrong. "Temporary holder" tmp should be an object that will temporarily hold data, not just a pointer to memory, that you are going to rewrite, thus declare it as struct entry tmp;:
struct entry tmp;
for( i = 0; i < ct; i++) {
for( j = 0; j < ct; j++ ) {
if ((dict[i].age) > (dict[j].age)) {
tmp = dict[i];
dict[i] = dict[j];
dict[j] = tmp;
}
}
}
By the way in the code you have posted, the ending curly brace (}) of your if is missing.
Try:
#include <stdio.h>
struct entry {
char name[15];
int age;
};
void entrySort( struct entry *dict, int);
void entrySort( struct entry *dict, int ct){
int i,j; // counters
/* int ct = 4; */
struct entry tmp; // temporary holder
for( i = 0; i < ct; i++){
for( j = 0; j < ct; j++ ){
if ((dict[i].age) > (dict[j].age)){ /* no * */
tmp = *(dict + i);
*(dict+i) = *(dict+j);
*(dict+j) = tmp;
}
}
}
int main (void){
int ct = 4, i;
struct entry reg[4] =
{{ "John", 24 },
{ "Alan", 18 },
{ "Jim", 40 },
{ "Sarah",32 }};
entrySort(reg, ct);
for( i = 0; i < ct; i++)
printf("name: %s. Age: %d\n", reg[i].name, reg[i].age);
return 0;
}
For completeness, here's how you'd do it with qsort:
#include <stdlib.h>
int sort_entry(const void *va, const void *vb) {
const struct entry *a = va;
const struct entry *b = vb;
if(a->age < b->age) return -1;
else if(a->age == b->age) return 0;
return 1;
}
...
qsort(reg, ct, sizeof(struct entry), sort_entry);